aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2019-10-14 08:05:52 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-10-14 08:05:52 +0000
commit56898e437a538c7edc0724a3650f5cb81c9d5721 (patch)
tree94c4cbef454873ea3d58380d67930ee520289c86 /gcc/c-family
parentb9424661f58de6c0aa9dc4c855c1fd913cc06282 (diff)
downloadgcc-56898e437a538c7edc0724a3650f5cb81c9d5721.zip
gcc-56898e437a538c7edc0724a3650f5cb81c9d5721.tar.gz
gcc-56898e437a538c7edc0724a3650f5cb81c9d5721.tar.bz2
[C] Avoid exposing internal details in aka types
The current aka diagnostics can sometimes leak internal details that seem more likely to be distracting than useful. E.g. on aarch64: void f (va_list *va) { *va = 1; } gives: incompatible types when assigning to type ‘va_list’ {aka ‘__va_list’} from type ‘int’ where __va_list isn't something the user is expected to know about. A similar thing happens for C++ on the arm_neon.h-based: float x; int8x8_t y = x; which gives: cannot convert ‘float’ to ‘int8x8_t’ {aka ‘__Int8x8_t’} in initialization This is accurate -- and __Int8x8_t is defined by the AArch64 PCS -- but it's not going to be meaningful to most users. This patch stops the aka code looking through typedefs if all of the following are true: (1) the typedef is built into the compiler or comes from a system header (2) the target of the typedef is anonymous or has a name in the implementation namespace (3) the target type is a tag type or vector type, which have in common that: (a) we print their type names if they have one (b) what we print for anonymous types isn't all that useful ("struct <anonymous>" etc. for tag types, pseudo-C "__vector(N) T" for vector types) The patch does this by recursively looking for the aka type, like the C++ frontend already does. This in turn makes "aka" work for distinct type copies like __Int8x8_t on aarch64, fixing the ??? in aarch64/diag_aka_1.c. 2019-10-14 Richard Sandiford <richard.sandiford@arm.com> gcc/c-family/ * c-common.h (user_facing_original_type_p): Declare. * c-common.c: Include c-spellcheck.h. (user_facing_original_type_p): New function. gcc/c/ * c-objc-common.c (useful_aka_type_p): Replace with... (get_aka_type): ...this new function. Given the original type, decide which aka type to print (if any). Only look through typedefs if user_facing_original_type_p. (print_type): Update accordingly. gcc/testsuite/ * gcc.dg/diag-aka-5.h: New test. * gcc.dg/diag-aka-5a.c: Likewise. * gcc.dg/diag-aka-5b.c: Likewise. * gcc.target/aarch64/diag_aka_1.c (f): Expect an aka to be printed for myvec. From-SVN: r276951
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-common.c47
-rw-r--r--gcc/c-family/c-common.h1
3 files changed, 54 insertions, 0 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 2b63689..cb3b9cf 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2019-10-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * c-common.h (user_facing_original_type_p): Declare.
+ * c-common.c: Include c-spellcheck.h.
+ (user_facing_original_type_p): New function.
+
2019-10-12 Jakub Jelinek <jakub@redhat.com>
* c-common.h (c_omp_mark_declare_variant,
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 909f52a..483d874 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimplify.h"
#include "substring-locations.h"
#include "spellcheck.h"
+#include "c-spellcheck.h"
#include "selftest.h"
cpp_reader *parse_in; /* Declared in c-pragma.h. */
@@ -7713,6 +7714,52 @@ set_underlying_type (tree x)
}
}
+/* Return true if it is worth exposing the DECL_ORIGINAL_TYPE of TYPE to
+ the user in diagnostics, false if it would be better to use TYPE itself.
+ TYPE is known to satisfy typedef_variant_p. */
+
+bool
+user_facing_original_type_p (const_tree type)
+{
+ gcc_assert (typedef_variant_p (type));
+ tree decl = TYPE_NAME (type);
+
+ /* Look through any typedef in "user" code. */
+ if (!DECL_IN_SYSTEM_HEADER (decl) && !DECL_IS_BUILTIN (decl))
+ return true;
+
+ /* If the original type is also named and is in the user namespace,
+ assume it too is a user-facing type. */
+ tree orig_type = DECL_ORIGINAL_TYPE (decl);
+ if (tree orig_id = TYPE_IDENTIFIER (orig_type))
+ if (!name_reserved_for_implementation_p (IDENTIFIER_POINTER (orig_id)))
+ return true;
+
+ switch (TREE_CODE (orig_type))
+ {
+ /* Don't look through to an anonymous vector type, since the syntax
+ we use for them in diagnostics isn't real C or C++ syntax.
+ And if ORIG_TYPE is named but in the implementation namespace,
+ TYPE is likely to be more meaningful to the user. */
+ case VECTOR_TYPE:
+ return false;
+
+ /* Don't expose anonymous tag types that are presumably meant to be
+ known by their typedef name. Also don't expose tags that are in
+ the implementation namespace, such as:
+
+ typedef struct __foo foo; */
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ return false;
+
+ /* Look through to anything else. */
+ default:
+ return true;
+ }
+}
+
/* Record the types used by the current global variable declaration
being parsed, so that we can decide later to emit their debug info.
Those types are in types_used_by_cur_var_decl, and we are going to
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index db7f26e..3bc021b 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1063,6 +1063,7 @@ extern tree builtin_type_for_size (int, bool);
extern void c_common_mark_addressable_vec (tree);
extern void set_underlying_type (tree);
+extern bool user_facing_original_type_p (const_tree);
extern void record_types_used_by_current_var_decl (tree);
extern vec<tree, va_gc> *make_tree_vector (void);
extern void release_tree_vector (vec<tree, va_gc> *);