diff options
author | Martin Uecker <uecker@tugraz.at> | 2023-10-14 09:09:07 +0200 |
---|---|---|
committer | Martin Uecker <uecker@tugraz.at> | 2023-10-17 20:19:12 +0200 |
commit | 1f186f64b8602d74769af4a6250255e51227f744 (patch) | |
tree | 104d609b11947646efcf8d66e0734b2027448d6a /gcc/c | |
parent | 5ac63ec5da2e93226457bea4dbb3a4f78d5d82c2 (diff) | |
download | gcc-1f186f64b8602d74769af4a6250255e51227f744.zip gcc-1f186f64b8602d74769af4a6250255e51227f744.tar.gz gcc-1f186f64b8602d74769af4a6250255e51227f744.tar.bz2 |
c: error for function with external and internal linkage [PR111708]
Declaring a function with both external and internal linkage
in the same TU is translation-time UB. Add an error for this
case as already done for objects.
PR c/111708
gcc/c/ChangeLog:
* c-decl.cc (grokdeclarator): Add error.
gcc/testsuite/ChangeLog:
* gcc.dg/pr111708-1.c: New test.
* gcc.dg/pr111708-2.c: New test.
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/c-decl.cc | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 5822faf..0de3847 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -8032,6 +8032,27 @@ grokdeclarator (const struct c_declarator *declarator, TREE_THIS_VOLATILE (decl) = 1; } } + + /* C99 6.2.2p7: It is invalid (compile-time undefined + behavior) to create an 'extern' declaration for a + function if there is a global declaration that is + 'static' and the global declaration is not visible. + (If the static declaration _is_ currently visible, + the 'extern' declaration is taken to refer to that decl.) */ + if (!initialized + && TREE_PUBLIC (decl) + && current_scope != file_scope) + { + tree global_decl = identifier_global_value (declarator->u.id.id); + tree visible_decl = lookup_name (declarator->u.id.id); + + if (global_decl + && global_decl != visible_decl + && VAR_OR_FUNCTION_DECL_P (global_decl) + && !TREE_PUBLIC (global_decl)) + error_at (loc, "function previously declared %<static%> " + "redeclared %<extern%>"); + } } else { |