aeubanks updated this revision to Diff 552889. aeubanks edited the summary of this revision. aeubanks added a comment.
add warning Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D158223/new/ https://reviews.llvm.org/D158223 Files: clang/include/clang/Basic/Attr.td clang/include/clang/Basic/AttrDocs.td clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Sema/SemaDecl.cpp clang/test/CodeGen/unnamed-addr.c clang/test/SemaCXX/unnamed-addr.cpp
Index: clang/test/SemaCXX/unnamed-addr.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/unnamed-addr.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct Foo { + int a; +}; + +struct Bar { + int a; + Bar(); +}; + +[[clang::unnamed_addr]] const int i = 8; + +[[clang::unnamed_addr]] int i2 = 8; // expected-warning{{unnamed_addr should only be used on const POD (plain old data) globals}} + +[[clang::unnamed_addr]] const Foo j = {2}; + +[[clang::unnamed_addr]] Foo j2 = {2}; // expected-warning{{unnamed_addr should only be used on const POD (plain old data) globals}} + +[[clang::unnamed_addr]] const Bar k; // expected-warning{{unnamed_addr should only be used on const POD (plain old data) globals}} Index: clang/test/CodeGen/unnamed-addr.c =================================================================== --- /dev/null +++ clang/test/CodeGen/unnamed-addr.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -O1 -emit-llvm -o - -disable-llvm-passes %s | FileCheck %s + +// CHECK: @i = unnamed_addr constant i32 8 + +[[clang::unnamed_addr]] const int i = 8; Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -14519,6 +14519,13 @@ PragmaClangRelroSection.PragmaLocation)); } + if (VD->hasGlobalStorage() && VD->isThisDeclarationADefinition() && + VD->hasAttr<UnnamedAddrAttr>() && + (!VD->getType().isPODType(getASTContext()) || + !VD->getType().isConstQualified())) { + Diag(VD->getLocation(), diag::warn_attribute_unnamed_addr); + } + if (auto *DD = dyn_cast<DecompositionDecl>(ThisDecl)) { for (auto *BD : DD->bindings()) { FinalizeDeclaration(BD); Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -5255,6 +5255,9 @@ GV->setConstant(true); } + if (D->hasAttr<UnnamedAddrAttr>()) + GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); + CharUnits AlignVal = getContext().getDeclAlign(D); // Check for alignment specifed in an 'omp allocate' directive. if (std::optional<CharUnits> AlignValFromAllocate = Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3587,6 +3587,9 @@ "weakref declaration of %0 must be in a global context">; def err_attribute_weakref_without_alias : Error< "weakref declaration of %0 must also have an alias attribute">; +def warn_attribute_unnamed_addr : Warning< + "unnamed_addr should only be used on const POD (plain old data) globals">, + InGroup<DiagGroup<"unnamed-addr">>; def err_alias_not_supported_on_darwin : Error < "aliases are not supported on darwin">; def warn_attribute_wrong_decl_type_str : Warning< Index: clang/include/clang/Basic/AttrDocs.td =================================================================== --- clang/include/clang/Basic/AttrDocs.td +++ clang/include/clang/Basic/AttrDocs.td @@ -1408,6 +1408,24 @@ }]; } +def UnnamedAddrDocs : Documentation { + let Category = DocCatField; + let Content = [{ +The ``clang::unnamed_addr`` attribute specifies that the address of a global is +not significant. This allows global constants with the same contents to be +merged. This can break global pointer identity, i.e. two different globals have +the same address. + +Example usage: + +.. code-block:: c + + // i and j may have the same address. + [[clang::unnamed_addr]] const int i = 42; + [[clang::unnamed_addr]] const int j = 42; + }]; +} + def ObjCRequiresSuperDocs : Documentation { let Category = DocCatFunction; let Content = [{ Index: clang/include/clang/Basic/Attr.td =================================================================== --- clang/include/clang/Basic/Attr.td +++ clang/include/clang/Basic/Attr.td @@ -1794,6 +1794,13 @@ let SimpleHandler = 1; } +def UnnamedAddr : InheritableAttr { + let Spellings = [Clang<"unnamed_addr">]; + let Subjects = SubjectList<[GlobalVar], ErrorDiag>; + let Documentation = [UnnamedAddrDocs]; + let SimpleHandler = 1; +} + def ReturnsTwice : InheritableAttr { let Spellings = [GCC<"returns_twice">]; let Subjects = SubjectList<[Function]>;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits