aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog7
-rw-r--r--gcc/c/c-decl.cc38
-rw-r--r--gcc/c/c-typeck.cc5
3 files changed, 45 insertions, 5 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 89a1bbe..3c37ba0 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,10 @@
+2025-10-27 H.J. Lu <hjl.tools@gmail.com>
+
+ PR c/122427
+ * c-decl.cc (diagnose_mismatched_decls): For FUNCTION_DECL, if
+ OLDDECL has TYPE_ATTRIBUTES and NEWDECL doesn't, try the type
+ with the OLDDECL attributes.
+
2025-10-24 Joseph Myers <josmyers@redhat.com>
* c-parser.cc (c_parser_next_tokens_start_typename)
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 061892a..2b31a43 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -2337,10 +2337,40 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
error ("conflicting type qualifiers for %q+D", newdecl);
}
else
- error ("conflicting types for %q+D; have %qT", newdecl, newtype);
- diagnose_arglist_conflict (newdecl, olddecl, newtype, oldtype);
- locate_old_decl (olddecl);
- return false;
+ {
+ if (TREE_CODE (olddecl) == FUNCTION_DECL)
+ {
+ tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (olddecl));
+ if (attrs && !TYPE_ATTRIBUTES (TREE_TYPE (newdecl)))
+ {
+ /* Similar to the C++ front-end, for FUNCTION_DECL,
+ if OLDDECL has attributes and NEWDECL doesn't,
+ try the type with OLDDECL attributes. */
+ tree rettype = TREE_TYPE (newtype);
+ tree tryargs = TYPE_ARG_TYPES (newtype);
+ tree trytype = c_build_function_type (rettype,
+ tryargs);
+ trytype = c_build_type_attribute_variant (trytype,
+ attrs);
+ if (comptypes (oldtype, trytype))
+ {
+ *newtypep = newtype = trytype;
+ comptypes_result = 1;
+ }
+ }
+ }
+
+ if (!comptypes_result)
+ error ("conflicting types for %q+D; have %qT", newdecl,
+ newtype);
+ }
+ if (!comptypes_result)
+ {
+ diagnose_arglist_conflict (newdecl, olddecl, newtype,
+ oldtype);
+ locate_old_decl (olddecl);
+ return false;
+ }
}
}
/* Warn about enum/integer type mismatches. They are compatible types
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 371583b..bc0fb6b 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -3179,7 +3179,10 @@ build_access_with_size_for_counted_by (location_t loc, tree ref,
tree result_type = is_fam ? c_build_pointer_type (TREE_TYPE (ref))
: TREE_TYPE (ref);
- tree element_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ref)));
+ tree element_type = TREE_TYPE (TREE_TYPE (ref));
+ tree element_size = VOID_TYPE_P (element_type)
+ ? build_one_cst (size_type_node)
+ : TYPE_SIZE_UNIT (element_type);
tree first_param = is_fam
? c_fully_fold (array_to_pointer_conversion (loc, ref),