Skip to content

[Sema] Add check for bitfield assignments to integral types #69049

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 1 commit into from
Oct 18, 2023

Conversation

vabridgers
Copy link
Contributor

This change introduces the bitfield conversion check after fixes to the test case. The original submission unfortunately did not comprehend differences in architecture for the diagnostic messages, leading to unanticipated failures in the arm build bots.

Original PR: #68276

Clang does not check for bitfield assignment widths, while gcc checks this.

gcc produced a warning like so for it's -Wconversion flag:

$ gcc -Wconversion -c test.c
test.c: In function 'foo':
test.c:10:15: warning: conversion from 'int' to 'signed char:7' may
change value [-Wconversion]
   10 |      vxx.bf = x; // no warning
      |               ^

This change simply adds this check for integral types under the -Wbitfield-conversion compiler option.

This change introduces the bitfield conversion check after fixes to the
test case. The original submission unfortunately did not comprehend
differences in architecture for the diagnostic messages, leading to
unanticipated failures in the arm build bots.

Original PR: llvm#68276

Clang does not check for bitfield assignment widths, while gcc checks this.

gcc produced a warning like so for it's -Wconversion flag:
```
$ gcc -Wconversion -c test.c
test.c: In function 'foo':
test.c:10:15: warning: conversion from 'int' to 'signed char:7' may
change value [-Wconversion]
   10 |      vxx.bf = x; // no warning
      |               ^
```

This change simply adds this check for integral types under the
-Wbitfield-conversion compiler option.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Oct 14, 2023
@llvmbot
Copy link
Member

llvmbot commented Oct 14, 2023

@llvm/pr-subscribers-clang

Author: None (vabridgers)

Changes

This change introduces the bitfield conversion check after fixes to the test case. The original submission unfortunately did not comprehend differences in architecture for the diagnostic messages, leading to unanticipated failures in the arm build bots.

Original PR: #68276

Clang does not check for bitfield assignment widths, while gcc checks this.

gcc produced a warning like so for it's -Wconversion flag:

$ gcc -Wconversion -c test.c
test.c: In function 'foo':
test.c:10:15: warning: conversion from 'int' to 'signed char:7' may
change value [-Wconversion]
   10 |      vxx.bf = x; // no warning
      |               ^

This change simply adds this check for integral types under the -Wbitfield-conversion compiler option.


Full diff: https://github.com/llvm/llvm-project/pull/69049.diff

5 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+3)
  • (modified) clang/include/clang/Basic/DiagnosticGroups.td (+2)
  • (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+3)
  • (modified) clang/lib/Sema/SemaChecking.cpp (+12-1)
  • (added) clang/test/SemaCXX/bitfield-width.c (+42)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2d918967e7f0b02..31969201a1cac8c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -185,6 +185,9 @@ New Compiler Flags
   the preprocessed text to the output. This can greatly reduce the size of the
   preprocessed output, which can be helpful when trying to reduce a test case.
 
+* ``-Wbitfield-conversion`` was added to detect assignments of integral
+  types to a bitfield that may change the value.
+
 Deprecated Compiler Flags
 -------------------------
 
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 0b09c002191848a..674eb9f4ef2e73f 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -53,6 +53,7 @@ def SingleBitBitFieldConstantConversion :
 def BitFieldConstantConversion : DiagGroup<"bitfield-constant-conversion",
                                            [SingleBitBitFieldConstantConversion]>;
 def BitFieldEnumConversion : DiagGroup<"bitfield-enum-conversion">;
+def BitFieldConversion : DiagGroup<"bitfield-conversion">;
 def BitFieldWidth : DiagGroup<"bitfield-width">;
 def CompoundTokenSplitByMacro : DiagGroup<"compound-token-split-by-macro">;
 def CompoundTokenSplitBySpace : DiagGroup<"compound-token-split-by-space">;
@@ -933,6 +934,7 @@ def Conversion : DiagGroup<"conversion",
                             ConstantConversion,
                             EnumConversion,
                             BitFieldEnumConversion,
+                            BitFieldConversion,
                             FloatConversion,
                             Shorten64To32,
                             IntConversion,
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c1a6e3831127e56..ab7fe881976aad2 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6171,6 +6171,9 @@ def warn_signed_bitfield_enum_conversion : Warning<
   "signed bit-field %0 needs an extra bit to represent the largest positive "
   "enumerators of %1">,
   InGroup<BitFieldEnumConversion>, DefaultIgnore;
+def warn_bitfield_too_small_for_integral_type : Warning<
+  "conversion from %2 (%3 bits) to bit-field %0 (%1 bits) may change value">,
+  InGroup<BitFieldConversion>, DefaultIgnore;
 def note_change_bitfield_sign : Note<
   "consider making the bitfield type %select{unsigned|signed}0">;
 
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 35b36db2049db09..cd61459cfbb13d6 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -14298,6 +14298,18 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
         S.Diag(WidthExpr->getExprLoc(), diag::note_widen_bitfield)
             << BitsNeeded << ED << WidthExpr->getSourceRange();
       }
+    } else if (OriginalInit->getType()->isIntegralType(S.Context)) {
+      IntRange LikelySourceRange =
+          GetExprRange(S.Context, Init, S.isConstantEvaluatedContext(),
+                       /*Approximate=*/true);
+
+      if (LikelySourceRange.Width > FieldWidth) {
+        Expr *WidthExpr = Bitfield->getBitWidth();
+        S.Diag(InitLoc, diag::warn_bitfield_too_small_for_integral_type)
+            << Bitfield << FieldWidth << OriginalInit->getType()
+            << LikelySourceRange.Width;
+        S.Diag(WidthExpr->getExprLoc(), diag::note_declared_at);
+      }
     }
 
     return false;
@@ -15195,7 +15207,6 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
 
   if (LikelySourceRange.Width > TargetRange.Width) {
     // If the source is a constant, use a default-on diagnostic.
-    // TODO: this should happen for bitfield stores, too.
     Expr::EvalResult Result;
     if (E->EvaluateAsInt(Result, S.Context, Expr::SE_AllowSideEffects,
                          S.isConstantEvaluatedContext())) {
diff --git a/clang/test/SemaCXX/bitfield-width.c b/clang/test/SemaCXX/bitfield-width.c
new file mode 100644
index 000000000000000..7b4e4444c245b0e
--- /dev/null
+++ b/clang/test/SemaCXX/bitfield-width.c
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -Wconversion -fsyntax-only -verify %s
+// RUN: %clang_cc1 -Wbitfield-conversion -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple armebv7-unknown-linux -Wbitfield-conversion \
+// RUN:     -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple arm64-unknown-linux  -Wbitfield-conversion \
+// RUN:     -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple arm-unknown-linux -Wbitfield-conversion \
+// RUN:     -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-unknown-linux -Wbitfield-conversion \
+// RUN:     -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple mipsel-unknown-linux -Wbitfield-conversion \
+// RUN:     -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple mips64el-unknown-linux -Wbitfield-conversion \
+// RUN:     -fsyntax-only -verify %s
+
+typedef struct _xx {
+     int bf:9; // expected-note 3{{declared here}}
+ } xx, *pxx; 
+
+ xx vxx;
+
+ void foo1(int x) {     
+     vxx.bf = x; // expected-warning{{conversion from 'int' (32 bits) to bit-field 'bf' (9 bits) may change value}}
+ } 
+ void foo2(short x) {     
+     vxx.bf = x; // expected-warning{{conversion from 'short' (16 bits) to bit-field 'bf' (9 bits) may change value}}
+ } 
+ void foo3(char x) {     
+     vxx.bf = x; // no warning expected
+ } 
+ void foo4(short x) {     
+     vxx.bf = 0xff & x; // no warning expected 
+ } 
+ void foo5(short x) {     
+     vxx.bf = 0x1ff & x; // no warning expected 
+ } 
+ void foo6(short x) {     
+     vxx.bf = 0x3ff & x; // expected-warning{{conversion from 'int' (10 bits) to bit-field 'bf' (9 bits) may change value}}
+ } 
+ int fee(void) {
+     return 0;
+ }

@vabridgers
Copy link
Contributor Author

Hi @AaronBallman , please let me know if you're ok with me merging this PR. This is a refinement of PR #68276. Thanks!

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Btw, if you're just repairing tests like you had to do here, you generally are okay to not go through another round of review unless you want an extra set of eyes on things. The original approval is fine so long as you're not making substantial changes to the code.

@vabridgers vabridgers merged commit 708808e into llvm:main Oct 18, 2023
@vabridgers vabridgers deleted the bitfield-warn-next branch October 18, 2023 20:28
@vabridgers
Copy link
Contributor Author

LGTM! Btw, if you're just repairing tests like you had to do here, you generally are okay to not go through another round of review unless you want an extra set of eyes on things. The original approval is fine so long as you're not making substantial changes to the code.

Thanks @AaronBallman !

vxx.bf = 0xff & x; // no warning expected
}
void foo5(short x) {
vxx.bf = 0x1ff & x; // no warning expected
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really non-ergonomic code pattern. Are we sure we can't come up with a better recommended code pattern for detecting and handling bitfield truncation?

xx vxx;

void foo1(int x) {
vxx.bf = x; // expected-warning{{conversion from 'int' (32 bits) to bit-field 'bf' (9 bits) may change value}}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will fire on the code pattern that I have been recommending in Clang to detect bitfield truncation:

  int value : 6;
  void setBitfield(int v) {
    value = v;
    assert(value == v && "truncation");
  }

Example:

ParmVarDeclBits.ParameterIndex = parameterIndex;
assert(ParmVarDeclBits.ParameterIndex == parameterIndex && "truncation!");

This isn't appropriate for all projects because not everyone uses assertions, but what's nice about it is that you don't have to do the truncation twice: the compiler figures out the bitwidth and truncates appropriately, so the developer doesn't have to duplicate information or create an extra enum to track the bitwidth to compute a mask. The assert can't really inform the warning because they are pre-processed away in release builds, but I wonder if we could detect equality comparisons between the assigned bitfield and the RHS of the assignment to suppress the warning. On second thought, that seems infeasible.

Without a better code pattern to recommend for developers, I'm worried that most of our users are going to turn this warning off. Can anyone more creative than me come up with a better recommended code pattern to suppress the warning?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm certainly not opposed to reducing the chattiness if there's an idea on how to do so. However, this is an off-by-default warning grouped under -Wconversion with its own diagnostic group (-Wbitfield-conversion) specifically to allow people to opt into conversion warnings while opting out of this new class of diagnostics. Is that insufficient?

Also, this is diagnosing code that GCC also diagnoses under -Wconversion.

https://godbolt.org/z/qYE8Kzr7f

@kadircet
Copy link
Member

hi folks!

this seems to be triggering crashes on some valid code, e.g:

a.cc:

template <class a, class... b>
bool c = __is_constructible(a, b...);

struct d {
  int q : 1;
};
struct i {
  virtual void g() { (void)c<d, int>; }
};
i n;
clang -xc++ -std=c++20 -fsyntax-only a.cc


clang: /usr/local/google/home/kadircet/repos/llvm/llvm/include/llvm/Support/Casting.h:662: decltype(auto) llvm::dyn_cast(From *) [To = clang::ParenExpr, From = clang::Expr]: Assertion `detail::isPresent(Val) && "dyn_cast on a non-existent value"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: ./clang -xc++ a.cc -fsyntax-only -std=c++20
1.      <eof> parser at end of file
2.      a.cc:3:6: instantiating variable definition 'c<d, int>'
3.      a.cc:3:6: instantiating variable definition 'c<d, int>'
 #0 0x0000560886f8bd57 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /usr/local/google/home/kadircet/repos/llvm/llvm/lib/Support/Unix/Signals.inc:723:13
 #1 0x0000560886f8993e llvm::sys::RunSignalHandlers() /usr/local/google/home/kadircet/repos/llvm/llvm/lib/Support/Signals.cpp:106:18
 #2 0x0000560886ef3698 HandleCrash /usr/local/google/home/kadircet/repos/llvm/llvm/lib/Support/CrashRecoveryContext.cpp:73:5
 #3 0x0000560886ef3698 CrashRecoverySignalHandler(int) /usr/local/google/home/kadircet/repos/llvm/llvm/lib/Support/CrashRecoveryContext.cpp:390:51
 #4 0x00007f1b0b05a510 (/lib/x86_64-linux-gnu/libc.so.6+0x3c510)
 #5 0x00007f1b0b0a80fc __pthread_kill_implementation ./nptl/./nptl/pthread_kill.c:44:76
 #6 0x00007f1b0b05a472 raise ./signal/../sysdeps/posix/raise.c:27:6
 #7 0x00007f1b0b0444b2 abort ./stdlib/./stdlib/abort.c:81:7
 #8 0x00007f1b0b0443d5 _nl_load_domain ./intl/./intl/loadmsgcat.c:1177:9
 #9 0x00007f1b0b0533a2 (/lib/x86_64-linux-gnu/libc.so.6+0x353a2)
#10 0x0000560889b511f5 clang::IgnoreParensSingleStep(clang::Expr*) /usr/local/google/home/kadircet/repos/llvm/clang/include/clang/AST/IgnoreExpr.h:0:0
#11 0x000056088a369e5b IgnoreExprNodes<clang::Expr *(&)(clang::Expr *)> /usr/local/google/home/kadircet/repos/llvm/clang/include/clang/AST/IgnoreExpr.h:36:12
#12 0x000056088a369e5b clang::Expr::IgnoreParens() /usr/local/google/home/kadircet/repos/llvm/clang/lib/AST/Expr.cpp:3012:10
#13 0x00005608895e4285 IgnoreParens /usr/local/google/home/kadircet/repos/llvm/clang/include/clang/AST/Expr.h:892:38
#14 0x00005608895e4285 GetExprRange(clang::ASTContext&, clang::Expr const*, unsigned int, bool, bool) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaChecking.cpp:13498:10
#15 0x00005608895e4341 GetExprRange(clang::ASTContext&, clang::Expr const*, unsigned int, bool, bool) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaChecking.cpp:0:0
#16 0x00005608895e4341 GetExprRange(clang::ASTContext&, clang::Expr const*, unsigned int, bool, bool) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaChecking.cpp:0:0
#17 0x00005608895d5970 AnalyzeBitFieldAssignment(clang::Sema&, clang::FieldDecl*, clang::Expr*, clang::SourceLocation) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaChecking.cpp:14337:11
#18 0x0000560889b37c84 getKind /usr/local/google/home/kadircet/repos/llvm/clang/include/clang/Sema/Initialization.h:441:39
#19 0x0000560889b37c84 clang::InitializationSequence::Perform(clang::Sema&, clang::InitializedEntity const&, clang::InitializationKind const&, llvm::MutableArrayRef<clang::Expr*>, clang::QualType*) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaInit.cpp:9424:34
#20 0x0000560889b4ee9b TryOrBuildParenListInitialization(clang::Sema&, clang::InitializedEntity const&, clang::InitializationKind const&, llvm::ArrayRef<clang::Expr*>, clang::InitializationSequence&, bool, clang::ActionResult<clang::Expr*, true>*)::$_12::operator()(clang::InitializedEntity const&, clang::InitializationKind const&, clang::Expr*, clang::Expr**) const /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaInit.cpp:0:0
#21 0x0000560889b3078b TryOrBuildParenListInitialization(clang::Sema&, clang::InitializedEntity const&, clang::InitializationKind const&, llvm::ArrayRef<clang::Expr*>, clang::InitializationSequence&, bool, clang::ActionResult<clang::Expr*, true>*) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaInit.cpp:0:14
#22 0x0000560889b35de0 clang::InitializationSequence::Perform(clang::Sema&, clang::InitializedEntity const&, clang::InitializationKind const&, llvm::MutableArrayRef<clang::Expr*>, clang::QualType*) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaInit.cpp:9395:7
#23 0x0000560889a6787c EvaluateBooleanTypeTrait /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaExprCXX.cpp:5505:30
#24 0x0000560889a6787c clang::Sema::BuildTypeTrait(clang::TypeTrait, clang::SourceLocation, llvm::ArrayRef<clang::TypeSourceInfo*>, clang::SourceLocation) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaExprCXX.cpp:5634:19
#25 0x0000560889eac70e RebuildTypeTrait /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/TreeTransform.h:3393:22
#26 0x0000560889eac70e clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformTypeTraitExpr(clang::TypeTraitExpr*) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/TreeTransform.h:12923:23
#27 0x0000560889e96bee clang::Sema::SubstInitializer(clang::Expr*, clang::MultiLevelTemplateArgumentList const&, bool) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaTemplateInstantiate.cpp:4085:23
#28 0x0000560889eef9e7 clang::Sema::InstantiateVariableInitializer(clang::VarDecl*, clang::VarDecl*, clang::MultiLevelTemplateArgumentList const&) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp:5417:14
#29 0x0000560889ef5079 getLangOpts /usr/local/google/home/kadircet/repos/llvm/clang/include/clang/Sema/Sema.h:1676:51
#30 0x0000560889ef5079 clang::Sema::CompleteVarTemplateSpecializationDecl(clang::VarTemplateSpecializationDecl*, clang::VarDecl*, clang::MultiLevelTemplateArgumentList const&) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp:5254:7
#31 0x0000560889ef5703 clang::Sema::InstantiateVariableDefinition(clang::SourceLocation, clang::VarDecl*, bool, bool, bool) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp:0:11
#32 0x0000560889ef65f9 clang::Sema::PerformPendingInstantiations(bool) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp:6466:3
#33 0x000056088950e895 ~TimeTraceScope /usr/local/google/home/kadircet/repos/llvm/llvm/include/llvm/Support/TimeProfiler.h:155:9
#34 0x000056088950e895 clang::Sema::ActOnEndOfTranslationUnitFragment(clang::Sema::TUFragmentKind) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/Sema.cpp:1082:3
#35 0x000056088950f03c clang::Sema::ActOnEndOfTranslationUnit() /usr/local/google/home/kadircet/repos/llvm/clang/lib/Sema/Sema.cpp:1123:9
#36 0x00005608893d236c clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Parse/Parser.cpp:0:13
#37 0x00005608893cce2e clang::ParseAST(clang::Sema&, bool, bool) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Parse/ParseAST.cpp:162:5
#38 0x0000560887b57360 clang::FrontendAction::Execute() /usr/local/google/home/kadircet/repos/llvm/clang/lib/Frontend/FrontendAction.cpp:1074:10
#39 0x0000560887ac4d8f getPtr /usr/local/google/home/kadircet/repos/llvm/llvm/include/llvm/Support/Error.h:276:42
#40 0x0000560887ac4d8f operator bool /usr/local/google/home/kadircet/repos/llvm/llvm/include/llvm/Support/Error.h:239:16
#41 0x0000560887ac4d8f clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Frontend/CompilerInstance.cpp:1045:23
#42 0x0000560887c3f8d7 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /usr/local/google/home/kadircet/repos/llvm/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:272:25
#43 0x00005608849d9d99 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /usr/local/google/home/kadircet/repos/llvm/clang/tools/driver/cc1_main.cpp:294:15
#44 0x00005608849d60b1 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) /usr/local/google/home/kadircet/repos/llvm/clang/tools/driver/driver.cpp:0:12
#45 0x0000560887922da9 operator() /usr/local/google/home/kadircet/repos/llvm/clang/lib/Driver/Job.cpp:440:30
#46 0x0000560887922da9 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool*) const::$_1>(long) /usr/local/google/home/kadircet/repos/llvm/llvm/include/llvm/ADT/STLFunctionalExtras.h:45:12
#47 0x0000560886ef33db operator() /usr/local/google/home/kadircet/repos/llvm/llvm/include/llvm/ADT/STLFunctionalExtras.h:0:12
#48 0x0000560886ef33db llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) /usr/local/google/home/kadircet/repos/llvm/llvm/lib/Support/CrashRecoveryContext.cpp:426:3
#49 0x0000560887922490 clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, bool*) const /usr/local/google/home/kadircet/repos/llvm/clang/lib/Driver/Job.cpp:440:7
#50 0x00005608878df438 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const /usr/local/google/home/kadircet/repos/llvm/clang/lib/Driver/Compilation.cpp:199:15
#51 0x00005608878df6f7 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&, bool) const /usr/local/google/home/kadircet/repos/llvm/clang/lib/Driver/Compilation.cpp:253:13
#52 0x00005608878ffd87 empty /usr/local/google/home/kadircet/repos/llvm/llvm/include/llvm/ADT/SmallVector.h:94:46
#53 0x00005608878ffd87 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*> >&) /usr/local/google/home/kadircet/repos/llvm/clang/lib/Driver/Driver.cpp:1884:23
#54 0x00005608849d534e clang_main(int, char**, llvm::ToolContext const&) /usr/local/google/home/kadircet/repos/llvm/clang/tools/driver/driver.cpp:542:21
#55 0x00005608849e6b41 main /usr/local/google/home/kadircet/repos/llvm/build/tools/clang/tools/driver/clang-driver.cpp:15:3
#56 0x00007f1b0b0456ca __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#57 0x00007f1b0b045785 call_init ./csu/../csu/libc-start.c:128:20
#58 0x00007f1b0b045785 __libc_start_main ./csu/../csu/libc-start.c:347:5
#59 0x00005608849d24a1 _start (./clang+0x58ca4a1)
clang: error: clang frontend command failed with exit code 134 (use -v to see invocation)
clang version 18.0.0 ([email protected]:llvm/llvm-project.git 01263c6c6fb495a94fe0ccbb1420bb1ec8460748)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/google/home/kadircet/repos/tmp/clang_crash/.
clang: note: diagnostic msg: 
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang: note: diagnostic msg: /tmp/a-7923c9.cpp
clang: note: diagnostic msg: /tmp/a-7923c9.sh
clang: note: diagnostic msg: 

********************

kadircet added a commit that referenced this pull request Oct 23, 2023
…69049)"

This reverts commit 708808e which is
causing crashes on valid code, see
#69049 (comment).
@AaronBallman
Copy link
Collaborator

It looks like these changes surfaced an existing bug with GetExprRange():

return GetExprRange(C, OVE->getSourceExpr(), MaxWidth, InConstantContext,

getSourceExpr() can return nullptr:

if (Expr *Source = Node->getSourceExpr())

if (auto *S = E->getSourceExpr())

if (const Expr *Source = OVE->getSourceExpr())

Note: I did not investigate whether the source expression should be null in this case, just verified that it can be and is in this code example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants