aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-decl.c
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2015-12-02 18:24:23 +0000
committerJoseph Myers <jsm28@gcc.gnu.org>2015-12-02 18:24:23 +0000
commite9e32ee6e8df82ba1d103ec2c501ecc7c185bc2e (patch)
treee7fbe443ab146c38eb72dcfc64ff8add5a7da19b /gcc/c/c-decl.c
parent701fa326a18df74cabd79cfef314ebbe5847d23b (diff)
downloadgcc-e9e32ee6e8df82ba1d103ec2c501ecc7c185bc2e.zip
gcc-e9e32ee6e8df82ba1d103ec2c501ecc7c185bc2e.tar.gz
gcc-e9e32ee6e8df82ba1d103ec2c501ecc7c185bc2e.tar.bz2
Fix TYPE_MAIN_VARIANT construction for arrays of qualified typedefs (PR c/68162).
PR c/68162 reports a spurious warning about incompatible types involving arrays of const double, constructed in one place using a typedef for const double and in another place literally using const double. The problem is that the array of the typedef was incorrectly constructed without a TYPE_MAIN_VARIANT being an array of unqualified elements as it should be (though it seems some more recent change resulted in this producing incorrect diagnostics, likely the support for C++-style handling of arrays of qualified type). This patch fixes the logic in grokdeclarator to determine first_non_attr_kind, which is used to determine whether it is necessary to use the TYPE_MAIN_VARIANT of the type in the declaration specifiers. However, fixing that logic introduces a failure of gcc.dg/debug/dwarf2/pr47939-4.c, a test introduced along with first_non_attr_kind. Thus, it is necessary to track the original qualified typedef when qualifying an array type, to use it rather than a newly-constructed type, to avoid regressing regarding typedef names in debug info. This is done along lines I suggested in <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47939#c6>: track the original type and the number of levels of array indirection at which it appears, and, in possibly affected cases, pass extra arguments to c_build_qualified_type (with default arguments to avoid needing to pass those extra arguments explicitly everywhere). Given Richard's recent fix to dwarf2out.c, this allows the C bug to be fixed without causing debug information regressions. Bootstrapped with no regressions on x86_64-pc-linux-gnu. gcc/c: PR c/68162 * c-decl.c (grokdeclarator): Set first_non_attr_kind before following link from declarator to next declarator. Track original qualified type and pass it to c_build_qualified_type. * c-typeck.c (c_build_qualified_type): Add arguments orig_qual_type and orig_qual_indirect. gcc/c-family: PR c/68162 * c-common.h (c_build_qualified_type): Add extra default arguments. gcc/cp: PR c/68162 * tree.c (c_build_qualified_type): Add extra arguments. gcc/testsuite: PR c/68162 * gcc.dg/pr68162-1.c: New test. From-SVN: r231194
Diffstat (limited to 'gcc/c/c-decl.c')
-rw-r--r--gcc/c/c-decl.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index efb0a52..9ad8219 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -5351,6 +5351,8 @@ grokdeclarator (const struct c_declarator *declarator,
tree returned_attrs = NULL_TREE;
bool bitfield = width != NULL;
tree element_type;
+ tree orig_qual_type = NULL;
+ size_t orig_qual_indirect = 0;
struct c_arg_info *arg_info = 0;
addr_space_t as1, as2, address_space;
location_t loc = UNKNOWN_LOCATION;
@@ -5389,9 +5391,9 @@ grokdeclarator (const struct c_declarator *declarator,
case cdk_function:
case cdk_pointer:
funcdef_syntax = (decl->kind == cdk_function);
- decl = decl->declarator;
if (first_non_attr_kind == cdk_attrs)
first_non_attr_kind = decl->kind;
+ decl = decl->declarator;
break;
case cdk_attrs:
@@ -5513,12 +5515,17 @@ grokdeclarator (const struct c_declarator *declarator,
if ((TREE_CODE (type) == ARRAY_TYPE
|| first_non_attr_kind == cdk_array)
&& TYPE_QUALS (element_type))
- type = TYPE_MAIN_VARIANT (type);
+ {
+ orig_qual_type = type;
+ type = TYPE_MAIN_VARIANT (type);
+ }
type_quals = ((constp ? TYPE_QUAL_CONST : 0)
| (restrictp ? TYPE_QUAL_RESTRICT : 0)
| (volatilep ? TYPE_QUAL_VOLATILE : 0)
| (atomicp ? TYPE_QUAL_ATOMIC : 0)
| ENCODE_QUAL_ADDR_SPACE (address_space));
+ if (type_quals != TYPE_QUALS (element_type))
+ orig_qual_type = NULL_TREE;
/* Applying the _Atomic qualifier to an array type (through the use
of typedefs or typeof) must be detected here. If the qualifier
@@ -6013,6 +6020,7 @@ grokdeclarator (const struct c_declarator *declarator,
array_ptr_attrs = NULL_TREE;
array_parm_static = 0;
}
+ orig_qual_indirect++;
break;
}
case cdk_function:
@@ -6022,6 +6030,7 @@ grokdeclarator (const struct c_declarator *declarator,
attributes. */
bool really_funcdef = false;
tree arg_types;
+ orig_qual_type = NULL_TREE;
if (funcdef_flag)
{
const struct c_declarator *t = declarator->declarator;
@@ -6122,7 +6131,9 @@ grokdeclarator (const struct c_declarator *declarator,
pedwarn (loc, OPT_Wpedantic,
"ISO C forbids qualified function types");
if (type_quals)
- type = c_build_qualified_type (type, type_quals);
+ type = c_build_qualified_type (type, type_quals, orig_qual_type,
+ orig_qual_indirect);
+ orig_qual_type = NULL_TREE;
size_varies = false;
/* When the pointed-to type involves components of variable size,
@@ -6304,7 +6315,8 @@ grokdeclarator (const struct c_declarator *declarator,
pedwarn (loc, OPT_Wpedantic,
"ISO C forbids qualified function types");
if (type_quals)
- type = c_build_qualified_type (type, type_quals);
+ type = c_build_qualified_type (type, type_quals, orig_qual_type,
+ orig_qual_indirect);
decl = build_decl (declarator->id_loc,
TYPE_DECL, declarator->u.id, type);
if (declspecs->explicit_signed_p)
@@ -6357,7 +6369,8 @@ grokdeclarator (const struct c_declarator *declarator,
pedwarn (loc, OPT_Wpedantic,
"ISO C forbids const or volatile function types");
if (type_quals)
- type = c_build_qualified_type (type, type_quals);
+ type = c_build_qualified_type (type, type_quals, orig_qual_type,
+ orig_qual_indirect);
return type;
}
@@ -6405,7 +6418,8 @@ grokdeclarator (const struct c_declarator *declarator,
/* Transfer const-ness of array into that of type pointed to. */
type = TREE_TYPE (type);
if (type_quals)
- type = c_build_qualified_type (type, type_quals);
+ type = c_build_qualified_type (type, type_quals, orig_qual_type,
+ orig_qual_indirect);
type = c_build_pointer_type (type);
type_quals = array_ptr_quals;
if (type_quals)
@@ -6496,7 +6510,8 @@ grokdeclarator (const struct c_declarator *declarator,
TYPE_DOMAIN (type) = build_range_type (sizetype, size_zero_node,
NULL_TREE);
}
- type = c_build_qualified_type (type, type_quals);
+ type = c_build_qualified_type (type, type_quals, orig_qual_type,
+ orig_qual_indirect);
decl = build_decl (declarator->id_loc,
FIELD_DECL, declarator->u.id, type);
DECL_NONADDRESSABLE_P (decl) = bitfield;
@@ -6608,7 +6623,8 @@ grokdeclarator (const struct c_declarator *declarator,
/* An uninitialized decl with `extern' is a reference. */
int extern_ref = !initialized && storage_class == csc_extern;
- type = c_build_qualified_type (type, type_quals);
+ type = c_build_qualified_type (type, type_quals, orig_qual_type,
+ orig_qual_indirect);
/* C99 6.2.2p7: It is invalid (compile-time undefined
behavior) to create an 'extern' declaration for a