llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) <details> <summary>Changes</summary> A constant expression gets its type from its subexpression, but if it has an APValue result, that result kind might not match the ast node type at all. E.g. it is currently perfectly possible to create a `ConstantExpr` of int type, but give it a float result. Such a mismatch can cause problems in later compilation stages since the value of a node and its evaluated result should match, in other words, the cached result and the subexpr should be interchangeable. This helps finding problems such as https://github.com/llvm/llvm-project/pull/227998 or the missing lvalue-to-rvalue conversion I added in this patch. --- Full diff: https://github.com/llvm/llvm-project/pull/230388.diff 2 Files Affected: - (modified) clang/lib/AST/Expr.cpp (+72) - (modified) clang/lib/Sema/SemaChecking.cpp (+2) ``````````diff diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 6b9aef5d479a61..5b6d3bf83c9936 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -319,6 +319,77 @@ 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()) { + assert((V.isInt() || V.isAddrLabelDiff()) && + "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 +455,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))); } `````````` </details> https://github.com/llvm/llvm-project/pull/230388 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
