-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[Clang] Use ExtWarn for static local variable in extern inline function (fixes #39524) #166332
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
base: main
Are you sure you want to change the base?
Conversation
|
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
|
@llvm/pr-subscribers-clang Author: V S Susi Krishna (Susikrishna) ChangesThis patch fixes incorrect behavior when compiling an inline function The diagnostic definition for A new test was added under Fixes: #39524 Full diff: https://github.com/llvm/llvm-project/pull/166332.diff 2 Files Affected:
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4e369be0bbb92..80272e24eced8 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6337,9 +6337,11 @@ def warn_c2y_compat_internal_in_extern_inline : Warning<
"using static %select{function|variable}0 %1 in an inline function with "
"external linkage is incompatible with standards before C2y">,
InGroup<CPre2yCompat>, DefaultIgnore;
-def warn_static_local_in_extern_inline : Warning<
- "non-constant static local variable in inline function may be different "
- "in different files">, InGroup<StaticLocalInInline>;
+def warn_static_local_in_extern_inline
+ : ExtWarn<"non-constant static local variable in inline function may be "
+ "different "
+ "in different files">,
+ InGroup<StaticLocalInInline>;
def note_convert_inline_to_static : Note<
"use 'static' to give inline function %0 internal linkage">;
diff --git a/clang/test/Sema/inline-static-var.c b/clang/test/Sema/inline-static-var.c
new file mode 100644
index 0000000000000..f622a7f22e02c
--- /dev/null
+++ b/clang/test/Sema/inline-static-var.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -std=c11 -Wno-unused-variable -Wno-deprecated-non-prototype -Wno-inline -pedantic-errors -verify %s
+
+inline void f(void) { // expected-note {{use 'static' to give inline function 'f' internal linkage}}
+ static int x; // expected-error {{non-constant static local variable in inline function may be different in different files}}
+}
+
+int main(void) { return 0; }
|
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 still needs a release note (in clang/docs/ReleaseNotes.rst).
| def warn_static_local_in_extern_inline | ||
| : ExtWarn<"non-constant static local variable in inline function may be " | ||
| "different " | ||
| "in different files">, | ||
| InGroup<StaticLocalInInline>; |
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.
clang-format doesn’t format these properly unfortunately... can you revert all changes here other than changing Warning to ExtWarn?
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.
Done. Added the release note and reverted unrelated formatting changes.
Co-authored-by: Sirraide <aeternalmail@gmail.com>
…tern inline functions
Co-authored-by: Sirraide <aeternalmail@gmail.com>
AaronBallman
left a comment
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.
LGTM aside from a nit
Co-authored-by: Aaron Ballman <aaron@aaronballman.com>
|
Precommit CI failure looks related: |
…istent diagnostics
Head branch was pushed to by a user without write access
| @@ -0,0 +1,6 @@ | |||
| // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -std=c11 -pedantic-errors -verify %s | |||
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 don't think the test should have a triple; I would expect this diagnostic to be target-agnostic based on the code which emits the diagnostic. Can you hook up a debugger to see why the diagnostic was being silenced on Windows targets in the first place?
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.
Hi @AaronBallman,
Thanks for the review. I checked it, and it seems the diagnostic is intentionally target-dependent. I'd be grateful if you could sanity-check my reasoning below:
My understanding is that this all comes down to the behavior of isFunctionDefinitionDiscarded() in this block in SemaDecl.cpp:
-
On Windows (MSVC): Clang emulates the MSVC model, where inline acts like C++ and is the "real" external definition. The linker just merges all the identical copies. Because this definition is not "discardable," isFunctionDefinitionDiscarded() returns false, and our diagnostic (correctly) doesn't fire.
-
On Linux (GNU): Clang uses the C99 model, where inline is just a "discardable copy" that's separate from the "real" definition. Because this definition is "discardable," isFunctionDefinitionDiscarded() returns true, which is what triggers our ExtWarn.
So, it seems the CI failed on Windows simply because, under MSVC's rules, this code isn't an error.
If that sounds right, then adding the -triple x86_64-pc-linux-gnu to the test file feels like the correct solution, as it forces the test to check against the GNU/C99 semantics we're actually trying to fix.
I'm not completely sure if this is the standard way to handle a target-specific test, though. Please let me know if there's a better approach!
AaronBallman
left a comment
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.
We've got competing changes, see #167086 for another implementation of this.
Please coordinate with the other author to come up with a single patch.
This patch fixes incorrect behavior when compiling an inline function
definition containing a static local variable with external linkage.
Previously, Clang emitted a warning instead of an error under
-pedantic-errors, violating C11 6.7.4/3.The diagnostic definition for
warn_static_local_in_extern_inlinewas changed from
WarningtoExtWarn.A new test was added under
clang/test/Sema/inline-static-var.cto verify that the behavior now matches the C standard and GCC’s output.
Fixes: #39524