From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1924) id 0FCC33858C2F; Tue, 17 Oct 2023 18:19:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0FCC33858C2F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1697566774; bh=7Cj5c8LHjxJWM/daHVakIEtWNjFA15/W4tXZhfTyecI=; h=From:To:Subject:Date:From; b=QZd8BLIN6e0gvL6Y8X3P8R6vp0W2paorI2YVxeSOhSHM95Y8/tdrH+zZVkUk8X3WW 3P9TvCIyNzF4PIEWDRfa2J7+heDsoYtguBhuhDfPnr8DTMKdSyfhYCdvRGTvgRBAy5 k/C3rVU+XLdI8X9cveCbSqUHa9L9DWSjvKP9mAEg= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Martin Uecker To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-4689] c: error for function with external and internal linkage [PR111708] X-Act-Checkin: gcc X-Git-Author: Martin Uecker X-Git-Refname: refs/heads/master X-Git-Oldrev: 5ac63ec5da2e93226457bea4dbb3a4f78d5d82c2 X-Git-Newrev: 1f186f64b8602d74769af4a6250255e51227f744 Message-Id: <20231017181934.0FCC33858C2F@sourceware.org> Date: Tue, 17 Oct 2023 18:19:34 +0000 (GMT) List-Id: https://gcc.gnu.org/g:1f186f64b8602d74769af4a6250255e51227f744 commit r14-4689-g1f186f64b8602d74769af4a6250255e51227f744 Author: Martin Uecker Date: Sat Oct 14 09:09:07 2023 +0200 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. Diff: --- gcc/c/c-decl.cc | 21 ++++++++++++++++++++ gcc/testsuite/gcc.dg/pr111708-1.c | 42 +++++++++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr111708-2.c | 21 ++++++++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 5822faf01b48..0de384783041 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 % " + "redeclared %"); + } } else { diff --git a/gcc/testsuite/gcc.dg/pr111708-1.c b/gcc/testsuite/gcc.dg/pr111708-1.c new file mode 100644 index 000000000000..4af7f53d75f0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr111708-1.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +extern int a(void); // external linkage (6.2.2p4) +static int a(void); /* { dg-error "static declaration of 'a' follows non-static declaration" } */ + +static int b(void); // internal linkage (6.2.2p3) +extern int b(void); // internal linkage (6.2.2p4) + +static int h0(void); + +void s(void) +{ + extern int h0(void); // internal linkage (6.2.2p4), + extern int h0(void); // internal linkage (6.2.2p4), redeclaration, ok + extern int h2(void); // external linkage (6.2.2p4) + extern int h2(void); // external linkage (6.2.2p4), redeclaration, ok. +} + + +extern int i(void); // external linkage (6.2.2p4) +static int j(void); // internal linkage (6.2.2p3) + +void bar(void) +{ + extern int i(void); // external linkage (6.2.2p4), ok +} + +void foo(void) +{ + extern int j(void); // internal linkage (6.2.2p4), ok, internal +} + +void x(void) +{ + int i(void); // no linkage (6.2.2p6) + int j; // no linkage (6.2.2p6) + { + extern int j(void); /* { dg-error "function previously declared 'static' redeclared 'extern'" } */ + } +} + diff --git a/gcc/testsuite/gcc.dg/pr111708-2.c b/gcc/testsuite/gcc.dg/pr111708-2.c new file mode 100644 index 000000000000..065c0525c2eb --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr111708-2.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ +/* { dg-require-effective-target trampolines } */ + +static void pp(void) +{ + int pp; + { + auto void pp(void); + void pp(void) { } + } +} + +static void q2(void); + +static void qq(void) +{ + auto void q2(void); + void q2(void) { } +} +