summaryrefslogtreecommitdiff
path: root/tools/gcc-plugins
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gcc-plugins')
-rw-r--r--tools/gcc-plugins/format-test.py51
-rw-r--r--tools/gcc-plugins/frr-format.c17
2 files changed, 48 insertions, 20 deletions
diff --git a/tools/gcc-plugins/format-test.py b/tools/gcc-plugins/format-test.py
index df2437d5bc..ddf71aa0ef 100644
--- a/tools/gcc-plugins/format-test.py
+++ b/tools/gcc-plugins/format-test.py
@@ -4,58 +4,71 @@ import shlex
import os
import re
-os.environ['LC_ALL'] = 'C'
-os.environ['LANG'] = 'C'
+os.environ["LC_ALL"] = "C"
+os.environ["LANG"] = "C"
for k in list(os.environ.keys()):
- if k.startswith('LC_'):
+ if k.startswith("LC_"):
os.environ.pop(k)
if len(sys.argv) < 2:
- sys.stderr.write('start as format-test.py gcc-123.45 [-options ...]\n')
+ sys.stderr.write("start as format-test.py gcc-123.45 [-options ...]\n")
sys.exit(1)
-c_re = re.compile(r'//\s+(NO)?WARN')
+c_re = re.compile(r"//\s+(NO)?WARN")
expect = {}
lines = {}
-with open('format-test.c', 'r') as fd:
+with open("format-test.c", "r") as fd:
for lno, line in enumerate(fd.readlines(), 1):
lines[lno] = line.strip()
m = c_re.search(line)
if m is None:
continue
if m.group(1) is None:
- expect[lno] = 'warn'
+ expect[lno] = "warn"
else:
- expect[lno] = 'nowarn'
+ expect[lno] = "nowarn"
-cmd = shlex.split('-Wall -Wextra -Wno-unused -fplugin=./frr-format.so -fno-diagnostics-show-caret -c -o format-test.o format-test.c')
+cmd = shlex.split(
+ "-Wall -Wextra -Wno-unused -fplugin=./frr-format.so -fno-diagnostics-show-caret -c -o format-test.o format-test.c"
+)
-gcc = subprocess.Popen(sys.argv[1:] + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+gcc = subprocess.Popen(
+ sys.argv[1:] + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE
+)
sout, serr = gcc.communicate()
gcc.wait()
-gcclines = serr.decode('UTF-8').splitlines()
-line_re = re.compile(r'^format-test\.c:(\d+):(.*)$')
+gcclines = serr.decode("UTF-8").splitlines()
+line_re = re.compile(r"^format-test\.c:(\d+):(.*)$")
gcc_warns = {}
for line in gcclines:
- if line.find('In function') >= 0:
+ if line.find("In function") >= 0:
continue
m = line_re.match(line)
if m is None:
- sys.stderr.write('cannot process GCC output: %s\n' % line)
+ sys.stderr.write("cannot process GCC output: %s\n" % line)
continue
lno = int(m.group(1))
gcc_warns.setdefault(lno, []).append(line)
for lno, val in expect.items():
- if val == 'nowarn' and lno in gcc_warns:
- sys.stderr.write('unexpected gcc warning on line %d:\n\t%s\n\t%s\n' % (lno, lines[lno], '\n\t'.join(gcc_warns[lno])))
- if val == 'warn' and lno not in gcc_warns:
- sys.stderr.write('expected warning on line %d but did not get one\n\t%s\n' % (lno, lines[lno]))
+ if val == "nowarn" and lno in gcc_warns:
+ sys.stderr.write(
+ "unexpected gcc warning on line %d:\n\t%s\n\t%s\n"
+ % (lno, lines[lno], "\n\t".join(gcc_warns[lno]))
+ )
+ if val == "warn" and lno not in gcc_warns:
+ sys.stderr.write(
+ "expected warning on line %d but did not get one\n\t%s\n"
+ % (lno, lines[lno])
+ )
leftover = set(gcc_warns.keys()) - set(expect.keys())
for lno in sorted(leftover):
- sys.stderr.write('unmarked gcc warning on line %d:\n\t%s\n\t%s\n' % (lno, lines[lno], '\n\t'.join(gcc_warns[lno])))
+ sys.stderr.write(
+ "unmarked gcc warning on line %d:\n\t%s\n\t%s\n"
+ % (lno, lines[lno], "\n\t".join(gcc_warns[lno]))
+ )
diff --git a/tools/gcc-plugins/frr-format.c b/tools/gcc-plugins/frr-format.c
index be56517171..6d91d2cdcd 100644
--- a/tools/gcc-plugins/frr-format.c
+++ b/tools/gcc-plugins/frr-format.c
@@ -2729,6 +2729,16 @@ tree type_normalize (tree type, tree *cousin, tree target = NULL)
return type;
}
+/* gcc-10 asserts when you give a TYPE_DECL instead of the actual TYPE */
+static tree
+decl_deref(tree typ)
+{
+ while (TREE_CODE (typ) == TYPE_DECL)
+ typ = DECL_ORIGINAL_TYPE (typ);
+
+ return typ;
+}
+
static void
check_format_types (const substring_loc &fmt_loc,
format_wanted_type *types, const format_kind_info *fki,
@@ -2750,6 +2760,8 @@ check_format_types (const substring_loc &fmt_loc,
wanted_type = types->wanted_type;
arg_num = types->arg_num;
+ wanted_type = decl_deref(wanted_type);
+
/* The following should not occur here. */
gcc_assert (wanted_type);
gcc_assert (wanted_type != void_type_node || types->pointer_count);
@@ -2873,7 +2885,7 @@ check_format_types (const substring_loc &fmt_loc,
|| cur_type == signed_char_type_node
|| cur_type == unsigned_char_type_node);
- int compat = lang_hooks.types_compatible_p (wanted_type, cur_type);
+ int compat = lang_hooks.types_compatible_p (decl_deref (wanted_type), decl_deref (cur_type));
/* Check the type of the "real" argument, if there's a type we want. */
if ((TREE_CODE (wanted_type) != INTEGER_TYPE || types->pointer_count)
&& compat)
@@ -3180,6 +3192,9 @@ matching_type_p (tree spec_type, tree arg_type)
gcc_assert (spec_type);
gcc_assert (arg_type);
+ spec_type = decl_deref (spec_type);
+ arg_type = decl_deref (arg_type);
+
/* If any of the types requires structural equality, we can't compare
their canonical types. */
if (TYPE_STRUCTURAL_EQUALITY_P (spec_type)