[clang][bytecode] Fix discarded LValueToRValueBitCasts (#140034)
We handle discarding fine, but we used to ignore all discarded cast
expressions. Handle bitcasts differently.
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 67b6ae4..2580fb1 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -474,10 +474,6 @@
return false;
return this->emitDecayPtr(*FromT, *ToT, CE);
}
-
- case CK_LValueToRValueBitCast:
- return this->emitBuiltinBitCast(CE);
-
case CK_IntegralToBoolean:
case CK_FixedPointToBoolean: {
// HLSL uses this to cast to one-element vectors.
@@ -736,6 +732,11 @@
}
template <class Emitter>
+bool Compiler<Emitter>::VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *E) {
+ return this->emitBuiltinBitCast(E);
+}
+
+template <class Emitter>
bool Compiler<Emitter>::VisitIntegerLiteral(const IntegerLiteral *LE) {
if (DiscardResult)
return true;
diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h
index ec5bd63..56a972f 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -126,6 +126,7 @@
// Expressions.
bool VisitCastExpr(const CastExpr *E);
+ bool VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *E);
bool VisitIntegerLiteral(const IntegerLiteral *E);
bool VisitFloatingLiteral(const FloatingLiteral *E);
bool VisitImaginaryLiteral(const ImaginaryLiteral *E);
diff --git a/clang/test/AST/ByteCode/builtin-bit-cast.cpp b/clang/test/AST/ByteCode/builtin-bit-cast.cpp
index 187f180..3c5e89d7 100644
--- a/clang/test/AST/ByteCode/builtin-bit-cast.cpp
+++ b/clang/test/AST/ByteCode/builtin-bit-cast.cpp
@@ -503,6 +503,16 @@
#endif
}
+namespace Discarded {
+ enum my_byte : unsigned char {};
+ struct pad {
+ char a;
+ int b;
+ };
+ constexpr int bad_my_byte = (__builtin_bit_cast(my_byte[8], pad{1, 2}), 0); // both-error {{must be initialized by a constant expression}} \
+ // both-note {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte';}}
+}
+
typedef bool bool9 __attribute__((ext_vector_type(9)));
// both-error@+2 {{constexpr variable 'bad_bool9_to_short' must be initialized by a constant expression}}
// both-note@+1 {{bit_cast involving type 'bool __attribute__((ext_vector_type(9)))' (vector of 9 'bool' values) is not allowed in a constant expression; element size 1 * element count 9 is not a multiple of the byte size 8}}