[clang] Don't short-circuit constant evaluation for array or record types
authorCharles Magahern <cmagahern@apple.com>
Mon, 9 Jan 2023 22:28:29 +0000 (14:28 -0800)
committerCharles Magahern <cmagahern@apple.com>
Fri, 20 Jan 2023 02:04:00 +0000 (18:04 -0800)
FastEvaluateAsRValue returns `true` without setting a result value for when a
given constant expression is an array or record type.

Clang attributes must be able to support constant expressions that are array or
record types, so proceed with the slower path for evaluation in the case where
`FastEvaluateAsRValue` does not yield an evaluation result.

Differential Revision: https://reviews.llvm.org/D141745

clang/lib/AST/ExprConstant.cpp
clang/test/CodeGen/2007-06-15-AnnotateAttribute.c

index 7105c7d..912a210 100644 (file)
@@ -15313,7 +15313,7 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx,
   assert(!isValueDependent() &&
          "Expression evaluator can't be called on a dependent expression.");
   bool IsConst;
-  if (FastEvaluateAsRValue(this, Result, Ctx, IsConst))
+  if (FastEvaluateAsRValue(this, Result, Ctx, IsConst) && Result.Val.hasValue())
     return true;
 
   ExprTimeTraceScope TimeScope(this, Ctx, "EvaluateAsConstantExpr");
index 754d716..05a9e6d 100644 (file)
@@ -14,6 +14,20 @@ int foo(int y __attribute__((annotate("LocalValAnnotation")))) {
   return y + x;
 }
 
+/* Attribute with struct argument. */
+struct TestStruct {
+  int a;
+  int b;
+};
+int Y __attribute__((annotate(
+  "GlobalValAnnotationWithArgs", 
+  42,
+  (struct TestStruct) { .a = 1, .b = 2 }
+)));
+
+// CHECK: @.str.3 = private unnamed_addr constant [28 x i8] c"GlobalValAnnotationWithArgs\00", section "llvm.metadata"
+// CHECK-NEXT: @.args = private unnamed_addr constant { i32, %struct.TestStruct } { i32 42, %struct.TestStruct { i32 1, i32 2 } }, section "llvm.metadata"
+
 int main(void) {
   static int a __attribute__((annotate("GlobalValAnnotation")));
   a = foo(2);