https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/230388

>From 94e6011e82d4bda003d632bcbe0ead03dc3116c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]>
Date: Fri, 9 Oct 2026 09:28:23 +0200
Subject: [PATCH] [clang][AST] Assert that ConstantExpr type and APValue kind
 match

---
 clang/lib/AST/Expr.cpp          | 74 +++++++++++++++++++++++++++++++++
 clang/lib/Sema/SemaChecking.cpp |  2 +
 2 files changed, 76 insertions(+)

diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 6b9aef5d479a61..1db296e1f54c52 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -319,6 +319,79 @@ ConstantResultStorageKind 
ConstantExpr::getStorageKind(const APValue &Value) {
   }
 }
 
+// Check that V is a valid APValue result of E, i.e. the node type needs to
+// match the APValue kind.
+static void assertAPValueKind(const ConstantExpr *E, const APValue &V) {
+  // FIXME: We shouldn't be creating ConstantExpr nodes for missing APValues in
+  // the first place, but for the time being, accept this for any type.
+  if (V.isAbsent())
+    return;
+
+  if (E->isGLValue()) {
+    // NOTE: The restrictions for lvalue expressions are not 100% clear. We
+    // can't assert(V.isLValue()) because some ConstantExprs are lvalue and
+    // their result is a string literal, so an Array.
+    assert((V.isLValue() || V.isArray()) &&
+           "a lvalue ConstantExpr needs an lvalue APValue");
+    return;
+  }
+
+  QualType T = E->getType();
+  if (T->isIntegralOrEnumerationType()) {
+    // An expression containing a PointerToIntegral cast gets evaluated to an
+    // LValue, so we have to allow LValue APValues here.
+    assert((V.isInt() || V.isAddrLabelDiff() || V.isLValue()) &&
+           "a ConstantExpr of integer type needs an int APValue result");
+    return;
+  }
+
+  if (T->isRealFloatingType()) {
+    assert(V.isFloat() &&
+           "a ConstantExpr of floating type needs a float APValue result");
+    return;
+  }
+
+  if (T->isAnyComplexType()) {
+    QualType ElemTy = T->getAs<ComplexType>()->getElementType();
+    if (ElemTy->isIntegralOrEnumerationType())
+      assert(V.isComplexInt() &&
+             "a complex int ConstantExpr needs a complex int APValue");
+    else if (ElemTy->isFloatingType())
+      assert(V.isComplexFloat() &&
+             "a complex float ConstantExpr needs a complex float APValue");
+    else
+      llvm_unreachable("Complex element types must be either float or int");
+    return;
+  }
+
+  if (T->isVectorType()) {
+    assert(V.isVector() && "a vector ConstantExpr needs a vector APValue");
+    return;
+  }
+
+  if (T->isMatrixType()) {
+    assert(V.isMatrix() && "a matrix ConstantExpr needs a matrix APValue");
+    return;
+  }
+
+  if (T->isPointerType()) {
+    assert(V.isLValue() && "a pointer ConstantExpr needs an lvalue APValue");
+    return;
+  }
+
+  if (T->isFixedPointType()) {
+    assert(V.isFixedPoint() &&
+           "a fixed point ConstantExpr needs a fixed point APValue");
+    return;
+  }
+
+  if (T->isMemberPointerType()) {
+    assert(V.isMemberPointer() &&
+           "a member pointer ConstantExpr needs a member pointer APValue");
+    return;
+  }
+}
+
 ConstantResultStorageKind
 ConstantExpr::getStorageKind(const Type *T, const ASTContext &Context) {
   if (T->isIntegralOrEnumerationType() && Context.getTypeInfo(T).Width <= 64)
@@ -384,6 +457,7 @@ ConstantExpr *ConstantExpr::CreateEmpty(const ASTContext 
&Context,
 void ConstantExpr::MoveIntoResult(APValue &Value, const ASTContext &Context) {
   assert((unsigned)getStorageKind(Value) <= ConstantExprBits.ResultKind &&
          "Invalid storage for this value kind");
+  assertAPValueKind(this, Value);
   ConstantExprBits.APValueKind = Value.getKind();
   switch (getResultStorageKind()) {
   case ConstantResultStorageKind::None:
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 0531dfa877fbdf..4d5b5d909fcbf4 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -6908,6 +6908,8 @@ bool Sema::BuiltinAssumeAligned(CallExpr *TheCall) {
       Diag(TheCall->getBeginLoc(), diag::warn_assume_aligned_too_great)
           << SecondArg->getSourceRange() << Sema::MaximumAlignment;
 
+    SecondArg = DefaultLvalueConversion(SecondArg).get();
+
     TheCall->setArg(1,
                     ConstantExpr::Create(Context, SecondArg, APValue(Result)));
   }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to