-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][AST] fix ast-print of extern <lang> with >=2 declarators, fixed #93913
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6286,7 +6286,7 @@ static FunctionDecl *rewriteBuiltinFunctionDecl(Sema *Sema, ASTContext &Context, | |
FunctionDecl *OverloadDecl = FunctionDecl::Create( | ||
Context, Parent, FDecl->getLocation(), FDecl->getLocation(), | ||
FDecl->getIdentifier(), OverloadTy, | ||
/*TInfo=*/nullptr, SC_Extern, Sema->getCurFPFeatures().isFPConstrained(), | ||
/*TInfo=*/nullptr, SC_None, Sema->getCurFPFeatures().isFPConstrained(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same concern here as above. |
||
false, | ||
/*hasPrototype=*/true); | ||
SmallVector<ParmVarDecl*, 16> Params; | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// RUN: %clang_cc1 -ast-print %s -o - | FileCheck %s | ||
|
||
// CHECK: extern "C" int printf(const char *, ...); | ||
extern "C" int printf(const char *...); | ||
|
||
// CHECK: extern "C++" int f(int); | ||
// CHECK-NEXT: extern "C++" int g(int); | ||
extern "C++" int f(int), g(int); | ||
|
||
// CHECK: extern "C" char a; | ||
// CHECK-NEXT: extern "C" char b; | ||
extern "C" char a, b; | ||
|
||
// CHECK: extern "C" { | ||
// CHECK-NEXT: void foo(); | ||
// CHECK-NEXT: int x; | ||
// CHECK-NEXT: int y; | ||
// CHECK-NEXT: extern short z; | ||
// CHECK-NEXT: } | ||
extern "C" { | ||
void foo(void); | ||
int x, y; | ||
extern short z; | ||
} | ||
|
||
// CHECK: extern "C" { | ||
// CHECK-NEXT: } | ||
extern "C" {} | ||
|
||
// CHECK: extern "C++"; | ||
extern "C++"; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change looks suspicious to me -- this is creating a builtin function, which should be modeled as an extern. In C++, you seem to be relying on the language linkage being sufficient for that, but C has no notion of language linkage and so I worry that the declaration for the builtin will be incorrectly handled in C.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, I also paid attention to that issue. However, when a storage class specifier is omitted for a function, it's storage class is implicitly supposed to be
extern
. Thus, it's fine.Furthermore, the meaning of this field according to the documentation comments is not for the actual storage duration or linkage, but for the storage-class specifier as present in the source code. Since builtins aren't really present in the source code, it seems further reasonable to omit a specifier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not actually correct -- the declaration of a function at block scope should definitely not be extern, it should have no linkage: https://godbolt.org/z/81fMaPaTq
Builtins should behave as-if they were declared in a header file that was included in the TU, and so they typically would be marked as
extern
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I may be wrong to rely on cppreference, but the following page tells that indeed a function at a block scope has implicit
extern
, which could also be made explicit: https://en.cppreference.com/w/c/language/storage_duration.I also checked your example locally by compiling (via clang)
main.c
with an additionaldefs.c
:main.c:
defs.c:
The executable works as expected.
I will also take a look at the C99 standard draft.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Paragraph 6.2.2.5 says:
Thus, seemingly confirming that a function declared at the block scope is declared with an implicit
extern
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, you're right, it's only objects declared at local scope that have no linkage (the following paragraph), not functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I've come around to being okay with these changes, thank you!