llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Arbaaz Ahmed (Arbaaz123676) <details> <summary>Changes</summary> Hi @<!-- -->llvmbot, Clang currently accepts a variable redeclaration with conflicting linkage (internal vs external) in the same translation unit without issuing a diagnostic. According to the C++ standard, redeclaring an entity with a different linkage in the same translation unit is ill-formed and requires a diagnostic. This patch adds a diagnostic in Sema::CheckVariableDeclaration to detect conflicting linkage during variable redeclaration and marks the declaration invalid. A regression test is added to ensure correct behavior. Note: Local check-clang reports unrelated failures on macOS; the added test passes. #<!-- -->178863 --- Full diff: https://github.com/llvm/llvm-project/pull/178900.diff 3 Files Affected: - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2) - (modified) clang/lib/Sema/SemaDecl.cpp (+14-2) - (added) clang/test/SemaCXX/redecl-linkage.cpp (+5) ``````````diff diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 807440c107897..3149142e1a86e 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6291,6 +6291,8 @@ def note_static_for_internal_linkage : Note< def err_static_data_member_reinitialization : Error<"static data member %0 already has an initializer">; def err_redefinition : Error<"redefinition of %0">; +def err_redefinition_different_linkage : + Error<"redeclaration of %0 with different linkage">; def err_alias_after_tentative : Error<"alias definition of %0 after tentative definition">; def err_alias_is_definition : diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 3b2c93b9fe7b5..7a445ab10fe25 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -9210,9 +9210,21 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous) { Previous.setShadowed(); if (!Previous.empty()) { - MergeVarDecl(NewVD, Previous); - return true; + if (auto *OldDecl = + dyn_cast<VarDecl>(Previous.getFoundDecl())) { + if (OldDecl->getFormalLinkage() != NewVD->getFormalLinkage()) { + Diag(NewVD->getLocation(), + diag::err_redefinition_different_linkage) + << NewVD->getName(); + NewVD->setInvalidDecl(); + return true; + } } + + MergeVarDecl(NewVD, Previous); + return true; +} + return false; } diff --git a/clang/test/SemaCXX/redecl-linkage.cpp b/clang/test/SemaCXX/redecl-linkage.cpp new file mode 100644 index 0000000000000..53cc35e878cd0 --- /dev/null +++ b/clang/test/SemaCXX/redecl-linkage.cpp @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -std=c++17 %s -verify + +static int k = 3; +extern int k; // expected-error {{redeclaration of k with different linkage}} + `````````` </details> https://github.com/llvm/llvm-project/pull/178900 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
