Skip to content

Commit 17198df

Browse files
committed
[AST] Fix recovery-expr crash on invalid aligned attr.
Summary: crash stack: ``` lang: tools/clang/include/clang/AST/AttrImpl.inc:1490: unsigned int clang::AlignedAttr::getAlignment(clang::ASTContext &) const: Assertion `!isAlignmentDependent()' failed. PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script. Stack dump: 0. Program arguments: ./bin/clang -cc1 -std=c++1y -ast-dump -frecovery-ast -fcxx-exceptions /tmp/t4.cpp 1. /tmp/t4.cpp:3:31: current parser token ';' #0 0x0000000002530cff llvm::sys::PrintStackTrace(llvm::raw_ostream&) llvm-project/llvm/lib/Support/Unix/Signals.inc:564:13 #1 0x000000000252ee30 llvm::sys::RunSignalHandlers() llvm-project/llvm/lib/Support/Signals.cpp:69:18 rust-lang#2 0x000000000253126c SignalHandler(int) llvm-project/llvm/lib/Support/Unix/Signals.inc:396:3 rust-lang#3 0x00007f86964d0520 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x13520) rust-lang#4 0x00007f8695f9ff61 raise /build/glibc-oCLvUT/glibc-2.29/signal/../sysdeps/unix/sysv/linux/raise.c:51:1 rust-lang#5 0x00007f8695f8b535 abort /build/glibc-oCLvUT/glibc-2.29/stdlib/abort.c:81:7 rust-lang#6 0x00007f8695f8b40f _nl_load_domain /build/glibc-oCLvUT/glibc-2.29/intl/loadmsgcat.c:1177:9 rust-lang#7 0x00007f8695f98b92 (/lib/x86_64-linux-gnu/libc.so.6+0x32b92) rust-lang#8 0x0000000004503d9f llvm::APInt::getZExtValue() const llvm-project/llvm/include/llvm/ADT/APInt.h:1623:5 rust-lang#9 0x0000000004503d9f clang::AlignedAttr::getAlignment(clang::ASTContext&) const llvm-project/build/tools/clang/include/clang/AST/AttrImpl.inc:1492:0 ``` Reviewers: sammccall Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D78085
1 parent c3c67e9 commit 17198df

File tree

5 files changed

+29
-4
lines changed

5 files changed

+29
-4
lines changed

clang/lib/AST/ComputeDependence.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ ExprDependence clang::computeDependence(UnaryExprOrTypeTraitExpr *E) {
7171
if (!D)
7272
return Deps;
7373
for (const auto *I : D->specific_attrs<AlignedAttr>()) {
74+
if (I->isAlignmentErrorDependent())
75+
Deps |= ExprDependence::Error;
7476
if (I->isAlignmentDependent())
75-
return Deps | ExprDependence::ValueInstantiation;
77+
Deps |= ExprDependence::ValueInstantiation;
7678
}
7779
return Deps;
7880
}

clang/lib/AST/DeclBase.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,10 @@ unsigned Decl::getMaxAlignment() const {
396396
const AttrVec &V = getAttrs();
397397
ASTContext &Ctx = getASTContext();
398398
specific_attr_iterator<AlignedAttr> I(V.begin()), E(V.end());
399-
for (; I != E; ++I)
400-
Align = std::max(Align, I->getAlignment(Ctx));
399+
for (; I != E; ++I) {
400+
if (!I->isAlignmentErrorDependent())
401+
Align = std::max(Align, I->getAlignment(Ctx));
402+
}
401403
return Align;
402404
}
403405

clang/test/AST/ast-dump-recovery.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,9 @@ struct Foo {} foo;
9797
void test(int x) {
9898
foo.abc;
9999
foo->func(x);
100-
}
100+
}
101+
102+
// CHECK: |-AlignedAttr {{.*}} alignas
103+
// CHECK-NEXT:| `-RecoveryExpr {{.*}} contains-errors
104+
// CHECK-NEXT:| `-UnresolvedLookupExpr {{.*}} 'invalid'
105+
struct alignas(invalid()) Aligned {};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: %clang_cc1 -frecovery-ast -verify %s
2+
// RUN: %clang_cc1 -verify %s
3+
4+
struct alignas(invalid()) Foo {}; // expected-error {{use of undeclared identifier}}
5+
6+
constexpr int k = alignof(Foo);

clang/utils/TableGen/ClangAttrEmitter.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ namespace {
481481

482482
void writeAccessors(raw_ostream &OS) const override {
483483
OS << " bool is" << getUpperName() << "Dependent() const;\n";
484+
OS << " bool is" << getUpperName() << "ErrorDependent() const;\n";
484485

485486
OS << " unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n";
486487

@@ -511,6 +512,15 @@ namespace {
511512
<< "Type->getType()->isDependentType();\n";
512513
OS << "}\n";
513514

515+
OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
516+
<< "ErrorDependent() const {\n";
517+
OS << " if (is" << getLowerName() << "Expr)\n";
518+
OS << " return " << getLowerName() << "Expr && " << getLowerName()
519+
<< "Expr->containsErrors();\n";
520+
OS << " return " << getLowerName()
521+
<< "Type->getType()->containsErrors();\n";
522+
OS << "}\n";
523+
514524
// FIXME: Do not do the calculation here
515525
// FIXME: Handle types correctly
516526
// A null pointer means maximum alignment

0 commit comments

Comments
 (0)