aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-decl.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2021-02-04 14:50:23 -0700
committerMartin Sebor <msebor@redhat.com>2021-02-04 14:53:38 -0700
commitce5720447c69286599b96bae53ae854b1bbe41fa (patch)
treeb7f6a4fb020f9b00c93319630e674f9aea57b92b /gcc/c/c-decl.c
parent4e7c24d97dd65083a770252ce942f43d408fe11d (diff)
downloadgcc-ce5720447c69286599b96bae53ae854b1bbe41fa.zip
gcc-ce5720447c69286599b96bae53ae854b1bbe41fa.tar.gz
gcc-ce5720447c69286599b96bae53ae854b1bbe41fa.tar.bz2
PR c/97882 - Segmentation Fault on improper redeclaration of function
gcc/c/ChangeLog: PR c/97882 * c-decl.c (locate_old_decl): Add type to diagnostic output. (diagnose_mismatched_decls): Same. (start_function): Introduce temporaries for better readability. * c-typeck.c (comptypes_internal): Only consider complete enum types in comparisons with integers. gcc/testsuite/ChangeLog: PR c/97882 * gcc.dg/decl-8.c: Adjust text of expected diagnostic. * gcc.dg/label-decl-4.c: Same. * gcc.dg/mismatch-decl-1.c: Same. * gcc.dg/old-style-then-proto-1.c: Same. * gcc.dg/parm-mismatch-1.c: Same. * gcc.dg/pr35445.c: Same. * gcc.dg/redecl-11.c: Same. * gcc.dg/redecl-12.c: Same. * gcc.dg/redecl-13.c: Same. * gcc.dg/redecl-15.c: Same. * gcc.dg/tls/thr-init-1.c: Same. * objc.dg/id-1.m: Same. * objc.dg/tls/diag-3.m: Same. * gcc.dg/pr97882.c: New test. * gcc.dg/qual-return-7.c: New test. * gcc.dg/qual-return-8.c: New test.
Diffstat (limited to 'gcc/c/c-decl.c')
-rw-r--r--gcc/c/c-decl.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index be95643..a5852a3 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -1910,15 +1910,22 @@ validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype)
static void
locate_old_decl (tree decl)
{
- if (TREE_CODE (decl) == FUNCTION_DECL && fndecl_built_in_p (decl)
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && fndecl_built_in_p (decl)
&& !C_DECL_DECLARED_BUILTIN (decl))
;
else if (DECL_INITIAL (decl))
- inform (input_location, "previous definition of %q+D was here", decl);
+ inform (input_location,
+ "previous definition of %q+D with type %qT",
+ decl, TREE_TYPE (decl));
else if (C_DECL_IMPLICIT (decl))
- inform (input_location, "previous implicit declaration of %q+D was here", decl);
+ inform (input_location,
+ "previous implicit declaration of %q+D with type %qT",
+ decl, TREE_TYPE (decl));
else
- inform (input_location, "previous declaration of %q+D was here", decl);
+ inform (input_location,
+ "previous declaration of %q+D with type %qT",
+ decl, TREE_TYPE (decl));
}
/* Subroutine of duplicate_decls. Compare NEWDECL to OLDDECL.
@@ -2083,7 +2090,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
&& C_DECL_IMPLICIT (olddecl) && !DECL_INITIAL (olddecl))
{
pedwarned = pedwarn (input_location, 0,
- "conflicting types for %q+D", newdecl);
+ "conflicting types for %q+D; have %qT",
+ newdecl, newtype);
/* Make sure we keep void as the return type. */
TREE_TYPE (olddecl) = *oldtypep = oldtype = newtype;
}
@@ -2119,7 +2127,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
error ("conflicting type qualifiers for %q+D", newdecl);
}
else
- error ("conflicting types for %q+D", newdecl);
+ error ("conflicting types for %q+D; have %qT", newdecl, newtype);
diagnose_arglist_conflict (newdecl, olddecl, newtype, oldtype);
locate_old_decl (olddecl);
return false;
@@ -9457,27 +9465,29 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
current_function_prototype_locus = UNKNOWN_LOCATION;
current_function_prototype_built_in = false;
current_function_prototype_arg_types = NULL_TREE;
- if (!prototype_p (TREE_TYPE (decl1)))
+ tree newtype = TREE_TYPE (decl1);
+ tree oldtype = old_decl ? TREE_TYPE (old_decl) : newtype;
+ if (!prototype_p (newtype))
{
+ tree oldrt = TREE_TYPE (oldtype);
+ tree newrt = TREE_TYPE (newtype);
if (old_decl != NULL_TREE
- && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE
- && comptypes (TREE_TYPE (TREE_TYPE (decl1)),
- TREE_TYPE (TREE_TYPE (old_decl))))
+ && TREE_CODE (oldtype) == FUNCTION_TYPE
+ && comptypes (oldrt, newrt))
{
- if (stdarg_p (TREE_TYPE (old_decl)))
+ if (stdarg_p (oldtype))
{
auto_diagnostic_group d;
warning_at (loc, 0, "%q+D defined as variadic function "
"without prototype", decl1);
locate_old_decl (old_decl);
}
- TREE_TYPE (decl1) = composite_type (TREE_TYPE (old_decl),
- TREE_TYPE (decl1));
+ TREE_TYPE (decl1) = composite_type (oldtype, newtype);
current_function_prototype_locus = DECL_SOURCE_LOCATION (old_decl);
current_function_prototype_built_in
= C_DECL_BUILTIN_PROTOTYPE (old_decl);
current_function_prototype_arg_types
- = TYPE_ARG_TYPES (TREE_TYPE (decl1));
+ = TYPE_ARG_TYPES (newtype);
}
if (TREE_PUBLIC (decl1))
{