Skip to content

Commit 1667a2a

Browse files
authored
[clang][ExprConst] Check record base classes for valid structs (llvm#132270)
In error cases, the base might be None. Fixes llvm#132257
1 parent ad0827d commit 1667a2a

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

clang/lib/AST/ExprConstant.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -7385,8 +7385,13 @@ class APValueToBufferConverter {
73857385
for (size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
73867386
const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
73877387
CXXRecordDecl *BaseDecl = BS.getType()->getAsCXXRecordDecl();
7388+
const APValue &Base = Val.getStructBase(I);
73887389

7389-
if (!visitRecord(Val.getStructBase(I), BS.getType(),
7390+
// Can happen in error cases.
7391+
if (!Base.isStruct())
7392+
return false;
7393+
7394+
if (!visitRecord(Base, BS.getType(),
73907395
Layout.getBaseClassOffset(BaseDecl) + Offset))
73917396
return false;
73927397
}

clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -527,3 +527,17 @@ namespace test_complex {
527527
constexpr double D = __builtin_bit_cast(double, test_float_complex);
528528
constexpr int M = __builtin_bit_cast(int, test_int_complex); // expected-error {{size of '__builtin_bit_cast' source type 'const _Complex unsigned int' does not match destination type 'int' (8 vs 4 bytes)}}
529529
}
530+
531+
namespace InvalidBaseClass {
532+
class F {
533+
public:
534+
char c;
535+
};
536+
537+
class InBetween : public F{};
538+
class E : public InBetween {
539+
public:
540+
constexpr E() : F{3} {} // expected-error {{not a direct or virtual base}}
541+
};
542+
static_assert(__builtin_bit_cast(char, E()) == 0); // expected-error {{not an integral constant expression}}
543+
}

0 commit comments

Comments
 (0)