aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-10-10 20:50:26 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2017-10-10 20:50:26 +0000
commit7cd6ea64f8b4abb51debc41cba2558fbda814a7f (patch)
treec15f011f48311e5e1b7d7bae22def9a7d3cb8785 /gcc
parent507ea98d58f471e00a717bc5e21ed8bdd240628b (diff)
downloadgcc-7cd6ea64f8b4abb51debc41cba2558fbda814a7f.zip
gcc-7cd6ea64f8b4abb51debc41cba2558fbda814a7f.tar.gz
gcc-7cd6ea64f8b4abb51debc41cba2558fbda814a7f.tar.bz2
[C++ PATCH] hash-table for extern-c fns.
https://gcc.gnu.org/ml/gcc-patches/2017-10/msg00614.html * name-lookup.c (extern_c_fns): Rename to ... (extern_c_decls): ... here. (check_extern_c_conflict, extern_c_linkage_bindings): Update. (do_pushdecl): Check extern-c fns and vars. * g++.dg/lookup/extern-c-redecl6.C: New. * g++.dg/lookup/extern-c-hidden.C: Adjust diagnostics. * g++.dg/lookup/extern-c-redecl.C: Likewise. * g++.old-deja/g++.other/using9.C: Likewise. From-SVN: r253622
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/name-lookup.c46
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/lookup/extern-c-hidden.C4
-rw-r--r--gcc/testsuite/g++.dg/lookup/extern-c-redecl.C2
-rw-r--r--gcc/testsuite/g++.dg/lookup/extern-c-redecl6.C25
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/using9.C2
7 files changed, 65 insertions, 26 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 25083eb..c0ca1f8 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
2017-10-10 Nathan Sidwell <nathan@acm.org>
+ * name-lookup.c (extern_c_fns): Rename to ...
+ (extern_c_decls): ... here.
+ (check_extern_c_conflict, extern_c_linkage_bindings): Update.
+ (do_pushdecl): Check extern-c fns and vars.
+
* cp-tree.h (default_hash_traits <lang_identifier *>): Delete
specialization.
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index ae30cf9..b1b4ebb 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2511,13 +2511,13 @@ update_binding (cp_binding_level *level, cxx_binding *binding, tree *slot,
return decl;
}
-/* Table of identifiers to extern C functions (or LISTS thereof). */
+/* Table of identifiers to extern C declarations (or LISTS thereof). */
-static GTY(()) hash_table<named_decl_hash> *extern_c_fns;
+static GTY(()) hash_table<named_decl_hash> *extern_c_decls;
-/* DECL has C linkage. If we have an existing instance, make sure it
- has the same exception specification [7.5, 7.6]. If there's no
- instance, add DECL to the map. */
+/* DECL has C linkage. If we have an existing instance, make sure the
+ new one is compatible. Make sure it has the same exception
+ specification [7.5, 7.6]. Add DECL to the map. */
static void
check_extern_c_conflict (tree decl)
@@ -2526,10 +2526,10 @@ check_extern_c_conflict (tree decl)
if (DECL_ARTIFICIAL (decl) || DECL_IN_SYSTEM_HEADER (decl))
return;
- if (!extern_c_fns)
- extern_c_fns = hash_table<named_decl_hash>::create_ggc (127);
+ if (!extern_c_decls)
+ extern_c_decls = hash_table<named_decl_hash>::create_ggc (127);
- tree *slot = extern_c_fns
+ tree *slot = extern_c_decls
->find_slot_with_hash (DECL_NAME (decl),
IDENTIFIER_HASH_VALUE (DECL_NAME (decl)), INSERT);
if (tree old = *slot)
@@ -2543,9 +2543,10 @@ check_extern_c_conflict (tree decl)
about a (possible) mismatch, when inserting the decl. */
else if (!decls_match (decl, old))
mismatch = 1;
- else if (!comp_except_specs (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (old)),
- TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)),
- ce_normal))
+ else if (TREE_CODE (decl) == FUNCTION_DECL
+ && !comp_except_specs (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (old)),
+ TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)),
+ ce_normal))
mismatch = -1;
else if (DECL_ASSEMBLER_NAME_SET_P (old))
SET_DECL_ASSEMBLER_NAME (decl, DECL_ASSEMBLER_NAME (old));
@@ -2553,12 +2554,12 @@ check_extern_c_conflict (tree decl)
if (mismatch)
{
pedwarn (input_location, 0,
- "declaration of %q#D with C language linkage", decl);
- pedwarn (DECL_SOURCE_LOCATION (old), 0,
- "conflicts with previous declaration %q#D", old);
+ "conflicting C language linkage declaration %q#D", decl);
+ inform (DECL_SOURCE_LOCATION (old),
+ "previous declaration %q#D", old);
if (mismatch < 0)
- pedwarn (input_location, 0,
- "due to different exception specifications");
+ inform (input_location,
+ "due to different exception specifications");
}
else
{
@@ -2587,8 +2588,8 @@ check_extern_c_conflict (tree decl)
tree
c_linkage_bindings (tree name)
{
- if (extern_c_fns)
- if (tree *slot = extern_c_fns
+ if (extern_c_decls)
+ if (tree *slot = extern_c_decls
->find_slot_with_hash (name, IDENTIFIER_HASH_VALUE (name), NO_INSERT))
{
tree result = *slot;
@@ -3030,9 +3031,8 @@ do_pushdecl (tree decl, bool is_friend)
else
*slot = head;
}
- if (TREE_CODE (match) == FUNCTION_DECL
- && DECL_EXTERN_C_P (match))
- /* We need to check and register the fn now. */
+ if (DECL_EXTERN_C_P (match))
+ /* We need to check and register the decl now. */
check_extern_c_conflict (match);
}
return match;
@@ -3113,7 +3113,9 @@ do_pushdecl (tree decl, bool is_friend)
}
else if (VAR_P (decl))
maybe_register_incomplete_var (decl);
- else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_EXTERN_C_P (decl))
+
+ if ((VAR_P (decl) || TREE_CODE (decl) == FUNCTION_DECL)
+ && DECL_EXTERN_C_P (decl))
check_extern_c_conflict (decl);
}
else
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b442420..f1ee90e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2017-10-10 Nathan Sidwell <nathan@acm.org>
+
+ * g++.dg/lookup/extern-c-redecl6.C: New.
+ * g++.dg/lookup/extern-c-hidden.C: Adjust diagnostics.
+ * g++.dg/lookup/extern-c-redecl.C: Likewise.
+ * g++.old-deja/g++.other/using9.C: Likewise.
+
2017-10-10 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/78006
diff --git a/gcc/testsuite/g++.dg/lookup/extern-c-hidden.C b/gcc/testsuite/g++.dg/lookup/extern-c-hidden.C
index a03dea0..80593db 100644
--- a/gcc/testsuite/g++.dg/lookup/extern-c-hidden.C
+++ b/gcc/testsuite/g++.dg/lookup/extern-c-hidden.C
@@ -1,11 +1,11 @@
// Make sure unhidding an extern-c still checks it is compatible
-extern "C" float fabsf (float); // { dg-error "conflicts with previous declaration" }
+extern "C" float fabsf (float); // { dg-message "previous declaration" }
namespace Bob
{
extern "C" float fabsf (float, float); // { dg-error "C language" }
- extern "C" double fabs (double, double); // { dg-error "conflicts with previous declaration" }
+ extern "C" double fabs (double, double); // { dg-message "previous declaration" }
}
extern "C" double fabs (double); // { dg-error "C language" }
diff --git a/gcc/testsuite/g++.dg/lookup/extern-c-redecl.C b/gcc/testsuite/g++.dg/lookup/extern-c-redecl.C
index 3e901cc..fd49868 100644
--- a/gcc/testsuite/g++.dg/lookup/extern-c-redecl.C
+++ b/gcc/testsuite/g++.dg/lookup/extern-c-redecl.C
@@ -3,7 +3,7 @@
// { dg-do compile }
namespace A {
- extern "C" void foo_func () throw(); // { dg-error "conflicts" }
+ extern "C" void foo_func () throw(); // { dg-message "previous" }
}
// next line should trigger an error because
// it conflicts with previous declaration of foo_func (), due to
diff --git a/gcc/testsuite/g++.dg/lookup/extern-c-redecl6.C b/gcc/testsuite/g++.dg/lookup/extern-c-redecl6.C
new file mode 100644
index 0000000..b4537d6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/extern-c-redecl6.C
@@ -0,0 +1,25 @@
+extern "C" {
+ int i; // { dg-message "previous" }
+ float f; // { dg-message "previous" }
+ void fn (); // { dg-message "previous" }
+ int ai1[1]; // { dg-message "previous" }
+ extern int ai[];
+
+ namespace OK
+ {
+ int i;
+ float f;
+ void fn ();
+ extern int ai1[];
+ int ai[2];
+ }
+
+ namespace BAD
+ {
+ long i; // { dg-error "C language linkage" }
+ double f; // { dg-error "C language linkage" }
+ int fn (); // { dg-error "C language linkage" }
+ int ai1[2]; // { dg-error "C language linkage" }
+ }
+}
+
diff --git a/gcc/testsuite/g++.old-deja/g++.other/using9.C b/gcc/testsuite/g++.old-deja/g++.other/using9.C
index 0e34156..c79f993 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/using9.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/using9.C
@@ -13,7 +13,7 @@ struct x {};
using ::x;
using ::a;
-extern "C" void foo (); // { dg-error "previous declaration" }
+extern "C" void foo (); // { dg-message "previous declaration" }
namespace {
extern "C" int foo (); // { dg-error "C.*linkage" }