[PATCH] Disabling of "redefine_extname" pragma for C++ code
Aaron Ballman
aaron.ballman at gmail.com
Thu Jul 9 04:55:39 PDT 2015
On Wed, Jul 8, 2015 at 5:50 PM, Andrey Bokhanko
<andreybokhanko at gmail.com> wrote:
> Aaron, thank you for investing your time for reviews! -- your comments
> give me a good run for my money, but patches definitely become better
> in result. :-)
My pleasure! :-)
~Aaron
>
> Yours,
> Andrey
>
>
> On Wed, Jul 8, 2015 at 9:48 PM, Aaron Ballman <aaron.ballman at gmail.com> wrote:
>> LGTM, but you should wait for Richard to weigh in as well.
>>
>> Thank you!
>>
>> ~Aaron
>>
>> On Wed, Jul 8, 2015 at 9:36 AM, Andrey Bokhanko
>> <andreybokhanko at gmail.com> wrote:
>>> Aaron, thank you! -- I fixed everything; please re-review:
>>> http://reviews.llvm.org/D10805
>>>
>>> Yours,
>>> Andrey
>>>
>>>
>>> On Tue, Jul 7, 2015 at 6:41 PM, Aaron Ballman <aaron.ballman at gmail.com> wrote:
>>>> On Tue, Jul 7, 2015 at 10:42 AM, Andrey Bokhanko
>>>> <andreybokhanko at gmail.com> wrote:
>>>>> Aaron, thank you for the review!
>>>>>
>>>>> I added a warning (for non applying pragma redefine_extname) and
>>>>> removed these nasty braces. :-)
>>>>>
>>>>> Please re-review: http://reviews.llvm.org/D10805.
>>>>
>>>>> Index: lib/Sema/SemaDecl.cpp
>>>>> ===================================================================
>>>>> --- lib/Sema/SemaDecl.cpp
>>>>> +++ lib/Sema/SemaDecl.cpp
>>>>> @@ -5561,15 +5561,12 @@
>>>>> return true;
>>>>> }
>>>>>
>>>>> -/// \brief Returns true if given declaration is TU-scoped and externally
>>>>> -/// visible.
>>>>> -static bool isDeclTUScopedExternallyVisible(const Decl *D) {
>>>>> +/// \brief Returns true if given declaration has external C language linkage.
>>>>> +static bool isDeclExternC(const Decl *D) {
>>>>> if (auto *FD = dyn_cast<FunctionDecl>(D))
>>>>> - return (FD->getDeclContext()->isTranslationUnit() || FD->isExternC()) &&
>>>>> - FD->hasExternalFormalLinkage();
>>>>> + return FD->isExternC();
>>>>> else if (auto *VD = dyn_cast<VarDecl>(D))
>>>>> - return (VD->getDeclContext()->isTranslationUnit() || VD->isExternC()) &&
>>>>> - VD->hasExternalFormalLinkage();
>>>>> + return VD->isExternC();
>>>>>
>>>>> llvm_unreachable("Unknown type of decl!");
>>>>> }
>>>>> @@ -5998,13 +5995,16 @@
>>>>>
>>>>> NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0),
>>>>> Context, Label, 0));
>>>>> - } else if (!ExtnameUndeclaredIdentifiers.empty() &&
>>>>> - isDeclTUScopedExternallyVisible(NewVD)) {
>>>>> + } else if (!ExtnameUndeclaredIdentifiers.empty()) {
>>>>> llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
>>>>> ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
>>>>> if (I != ExtnameUndeclaredIdentifiers.end()) {
>>>>> - NewVD->addAttr(I->second);
>>>>> - ExtnameUndeclaredIdentifiers.erase(I);
>>>>> + if (isDeclExternC(NewVD)) {
>>>>> + NewVD->addAttr(I->second);
>>>>> + ExtnameUndeclaredIdentifiers.erase(I);
>>>>> + } else
>>>>> + Diag(NewVD->getLocation(), diag::warn_redefine_extname_not_applied)
>>>>> + << 1 << NewVD->getName();
>>>>
>>>> You can leave off the ->getName() part and just pass in the Decl *.
>>>> Also, can you change 1 into /*Variable*/1?
>>>>
>>>>> }
>>>>> }
>>>>>
>>>>> @@ -7526,13 +7526,16 @@
>>>>> StringLiteral *SE = cast<StringLiteral>(E);
>>>>> NewFD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context,
>>>>> SE->getString(), 0));
>>>>> - } else if (!ExtnameUndeclaredIdentifiers.empty() &&
>>>>> - isDeclTUScopedExternallyVisible(NewFD)) {
>>>>> + } else if (!ExtnameUndeclaredIdentifiers.empty()) {
>>>>> llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
>>>>> ExtnameUndeclaredIdentifiers.find(NewFD->getIdentifier());
>>>>> if (I != ExtnameUndeclaredIdentifiers.end()) {
>>>>> - NewFD->addAttr(I->second);
>>>>> - ExtnameUndeclaredIdentifiers.erase(I);
>>>>> + if (isDeclExternC(NewFD)) {
>>>>> + NewFD->addAttr(I->second);
>>>>> + ExtnameUndeclaredIdentifiers.erase(I);
>>>>> + } else
>>>>> + Diag(NewFD->getLocation(), diag::warn_redefine_extname_not_applied)
>>>>> + << 0 << NewFD->getName();
>>>>
>>>> Same suggestions here.
>>>>
>>>>> }
>>>>> }
>>>>>
>>>>> @@ -14355,12 +14358,14 @@
>>>>> // 1) declares a function or a variable
>>>>> // 2) has external linkage
>>>>> // already exists, add a label attribute to it.
>>>>> - if (PrevDecl &&
>>>>> - (isa<FunctionDecl>(PrevDecl) || isa<VarDecl>(PrevDecl)) &&
>>>>> - PrevDecl->hasExternalFormalLinkage())
>>>>> - PrevDecl->addAttr(Attr);
>>>>> + if (PrevDecl && (isa<FunctionDecl>(PrevDecl) || isa<VarDecl>(PrevDecl))) {
>>>>> + if (isDeclExternC(PrevDecl)) {
>>>>> + PrevDecl->addAttr(Attr);
>>>>> + } else
>>>>
>>>> Elide the braces. :-)
>>>>
>>>>> + Diag(PrevDecl->getLocation(), diag::warn_redefine_extname_not_applied)
>>>>> + << (isa<FunctionDecl>(PrevDecl) ? 0 : 1) << Name->getName();
>>>>
>>>> And here. :-)
>>>>
>>>>> // Otherwise, add a label atttibute to ExtnameUndeclaredIdentifiers.
>>>>> - else
>>>>> + } else
>>>>> (void)ExtnameUndeclaredIdentifiers.insert(std::make_pair(Name, Attr));
>>>>> }
>>>>>
>>>>> Index: include/clang/Basic/DiagnosticSemaKinds.td
>>>>> ===================================================================
>>>>> --- include/clang/Basic/DiagnosticSemaKinds.td
>>>>> +++ include/clang/Basic/DiagnosticSemaKinds.td
>>>>> @@ -6333,6 +6333,10 @@
>>>>> InGroup<CastQual>, DefaultIgnore;
>>>>> def warn_cast_qual2 : Warning<"cast from %0 to %1 must have all intermediate "
>>>>> "pointers const qualified to be safe">, InGroup<CastQual>, DefaultIgnore;
>>>>> +def warn_redefine_extname_not_applied : Warning<
>>>>> + "pragma redefine_extname is applicable to external C declarations only; "
>>>>> + "not applied to %select{function|variable}0 '%1'">,
>>>>> + InGroup<Pragmas>;
>>>>
>>>> Should be #pragma instead of pragma.
>>>>
>>>> If you remove the getName() from above, you can remove the single
>>>> quotes around %1. The diagnostic emitter will automatically quote
>>>> things as appropriate then.
>>>>
>>>>> } // End of general sema category.
>>>>>
>>>>> // inline asm.
>>>>> Index: test/CodeGen/redefine_extname.c
>>>>> ===================================================================
>>>>> --- test/CodeGen/redefine_extname.c
>>>>> +++ test/CodeGen/redefine_extname.c
>>>>> @@ -1,4 +1,4 @@
>>>>> -// RUN: %clang_cc1 -triple=i386-pc-solaris2.11 -w -emit-llvm %s -o - | FileCheck %s
>>>>> +// RUN: %clang_cc1 -triple=i386-pc-solaris2.11 -Wpragmas -emit-llvm %s -o - | FileCheck %s
>>>>>
>>>>> #pragma redefine_extname fake real
>>>>> #pragma redefine_extname name alias
>>>>> @@ -24,3 +24,9 @@
>>>>> extern int foo() { return 1; }
>>>>> // CHECK: define i32 @bar()
>>>>>
>>>>> +// Check that pragma redefine_extname applies to external declarations only.
>>>>> +#pragma redefine_extname foo_static bar_static
>>>>> +static int foo_static() { return 1; }
>>>>> +int baz() { return foo_static(); } // expected-warning {{pragma redefine_extname is applicable to external C declarations only; not applied to function 'foo_static'}}
>>>>
>>>> From reading this warning, I find the wording slightly confusing
>>>> because it's talking about the function foo_static on a function call
>>>> expression, but not on the function definition. I would have expected
>>>> the diagnostic to follow the declaration, not the expression?
>>>>
>>>>> +// CHECK-NOT: call i32 @bar_static()
>>>>> +
>>>>> Index: test/CodeGenCXX/redefine_extname.cpp
>>>>> ===================================================================
>>>>> --- test/CodeGenCXX/redefine_extname.cpp
>>>>> +++ test/CodeGenCXX/redefine_extname.cpp
>>>>> @@ -1,4 +1,4 @@
>>>>> -// RUN: %clang_cc1 -triple=i386-pc-solaris2.11 -w -emit-llvm %s -o - | FileCheck %s
>>>>> +// RUN: %clang_cc1 -triple=i386-pc-solaris2.11 -verify -Wpragmas -emit-llvm %s -o - | FileCheck %s
>>>>>
>>>>> extern "C" {
>>>>> struct statvfs64 {
>>>>> @@ -20,11 +20,17 @@
>>>>> // same name. PR23923.
>>>>> #pragma redefine_extname foo bar
>>>>> int f() {
>>>>> - int foo = 0;
>>>>> + int foo = 0; // expected-warning {{pragma redefine_extname is applicable to external C declarations only; not applied to variable 'foo'}}
>>>>> return foo;
>>>>> }
>>>>> extern "C" {
>>>>> int foo() { return 1; }
>>>>> // CHECK: define i32 @bar()
>>>>> }
>>>>>
>>>>> +// Check that pragma redefine_extname applies to C code only, and shouldn't be
>>>>> +// applied to C++.
>>>>> +#pragma redefine_extname foo_cpp bar_cpp
>>>>> +extern int foo_cpp() { return 1; } // expected-warning {{pragma redefine_extname is applicable to external C declarations only; not applied to function 'foo_cpp'}}
>>>>> +// CHECK-NOT: define i32 @bar_cpp()
>>>>> +
>>>>>
>>>>
>>>> ~Aaron
More information about the cfe-commits
mailing list