mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 23:51:56 +00:00
Relax assert in ExprConstant to a return None.
Fixes a compiler assert on passing a compile time integer to atomic builtins. Assert introduced in D61522 Function changed from ->bool to ->Optional in D76646 Simplifies call sites to getIntegerConstantExpr to elide the now-redundant isValueDependent checks. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D112159
This commit is contained in:
parent
b8b14b682c
commit
7ff4f48adb
@ -15501,8 +15501,10 @@ bool Expr::isIntegerConstantExpr(const ASTContext &Ctx,
|
||||
Optional<llvm::APSInt> Expr::getIntegerConstantExpr(const ASTContext &Ctx,
|
||||
SourceLocation *Loc,
|
||||
bool isEvaluated) const {
|
||||
assert(!isValueDependent() &&
|
||||
"Expression evaluator can't be called on a dependent expression.");
|
||||
if (isValueDependent()) {
|
||||
// Expression evaluator can't succeed on a dependent expression.
|
||||
return None;
|
||||
}
|
||||
|
||||
APSInt Value;
|
||||
|
||||
|
@ -340,7 +340,7 @@ void Sema::ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action,
|
||||
|
||||
// pack(0) is like pack(), which just works out since that is what
|
||||
// we use 0 for in PackAttr.
|
||||
if (Alignment->isTypeDependent() || Alignment->isValueDependent() || !Val ||
|
||||
if (Alignment->isTypeDependent() || !Val ||
|
||||
!(*Val == 0 || Val->isPowerOf2()) || Val->getZExtValue() > 16) {
|
||||
Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
|
||||
return; // Ignore
|
||||
|
@ -216,7 +216,7 @@ static bool checkUInt32Argument(Sema &S, const AttrInfo &AI, const Expr *Expr,
|
||||
uint32_t &Val, unsigned Idx = UINT_MAX,
|
||||
bool StrictlyUnsigned = false) {
|
||||
Optional<llvm::APSInt> I = llvm::APSInt(32);
|
||||
if (Expr->isTypeDependent() || Expr->isValueDependent() ||
|
||||
if (Expr->isTypeDependent() ||
|
||||
!(I = Expr->getIntegerConstantExpr(S.Context))) {
|
||||
if (Idx != UINT_MAX)
|
||||
S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
|
||||
@ -308,7 +308,7 @@ static bool checkFunctionOrMethodParameterIndex(
|
||||
(HP ? getFunctionOrMethodNumParams(D) : 0) + HasImplicitThisParam;
|
||||
|
||||
Optional<llvm::APSInt> IdxInt;
|
||||
if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
|
||||
if (IdxExpr->isTypeDependent() ||
|
||||
!(IdxInt = IdxExpr->getIntegerConstantExpr(S.Context))) {
|
||||
S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
|
||||
<< &AI << AttrArgNum << AANT_ArgumentIntegerConstant
|
||||
@ -2860,8 +2860,7 @@ static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
|
||||
if (AL.getNumArgs() > 0) {
|
||||
Expr *E = AL.getArgAsExpr(0);
|
||||
Optional<llvm::APSInt> Idx = llvm::APSInt(32);
|
||||
if (E->isTypeDependent() || E->isValueDependent() ||
|
||||
!(Idx = E->getIntegerConstantExpr(S.Context))) {
|
||||
if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(S.Context))) {
|
||||
S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
|
||||
<< AL << 1 << AANT_ArgumentIntegerConstant << E->getSourceRange();
|
||||
return;
|
||||
@ -2880,8 +2879,7 @@ static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
|
||||
if (AL.getNumArgs() > 1) {
|
||||
Expr *E = AL.getArgAsExpr(1);
|
||||
Optional<llvm::APSInt> Idx = llvm::APSInt(32);
|
||||
if (E->isTypeDependent() || E->isValueDependent() ||
|
||||
!(Idx = E->getIntegerConstantExpr(S.Context))) {
|
||||
if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(S.Context))) {
|
||||
S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
|
||||
<< AL << 2 << AANT_ArgumentIntegerConstant << E->getSourceRange();
|
||||
return;
|
||||
|
@ -2137,39 +2137,38 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
|
||||
// Let's see if this is a constant < 0. If so, we reject it out of hand,
|
||||
// per CWG1464. Otherwise, if it's not a constant, we must have an
|
||||
// unparenthesized array type.
|
||||
if (!(*ArraySize)->isValueDependent()) {
|
||||
// We've already performed any required implicit conversion to integer or
|
||||
// unscoped enumeration type.
|
||||
// FIXME: Per CWG1464, we are required to check the value prior to
|
||||
// converting to size_t. This will never find a negative array size in
|
||||
// C++14 onwards, because Value is always unsigned here!
|
||||
if (Optional<llvm::APSInt> Value =
|
||||
(*ArraySize)->getIntegerConstantExpr(Context)) {
|
||||
if (Value->isSigned() && Value->isNegative()) {
|
||||
return ExprError(Diag((*ArraySize)->getBeginLoc(),
|
||||
diag::err_typecheck_negative_array_size)
|
||||
<< (*ArraySize)->getSourceRange());
|
||||
}
|
||||
|
||||
if (!AllocType->isDependentType()) {
|
||||
unsigned ActiveSizeBits = ConstantArrayType::getNumAddressingBits(
|
||||
Context, AllocType, *Value);
|
||||
if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context))
|
||||
return ExprError(
|
||||
Diag((*ArraySize)->getBeginLoc(), diag::err_array_too_large)
|
||||
<< toString(*Value, 10) << (*ArraySize)->getSourceRange());
|
||||
}
|
||||
|
||||
KnownArraySize = Value->getZExtValue();
|
||||
} else if (TypeIdParens.isValid()) {
|
||||
// Can't have dynamic array size when the type-id is in parentheses.
|
||||
Diag((*ArraySize)->getBeginLoc(), diag::ext_new_paren_array_nonconst)
|
||||
<< (*ArraySize)->getSourceRange()
|
||||
<< FixItHint::CreateRemoval(TypeIdParens.getBegin())
|
||||
<< FixItHint::CreateRemoval(TypeIdParens.getEnd());
|
||||
|
||||
TypeIdParens = SourceRange();
|
||||
// We've already performed any required implicit conversion to integer or
|
||||
// unscoped enumeration type.
|
||||
// FIXME: Per CWG1464, we are required to check the value prior to
|
||||
// converting to size_t. This will never find a negative array size in
|
||||
// C++14 onwards, because Value is always unsigned here!
|
||||
if (Optional<llvm::APSInt> Value =
|
||||
(*ArraySize)->getIntegerConstantExpr(Context)) {
|
||||
if (Value->isSigned() && Value->isNegative()) {
|
||||
return ExprError(Diag((*ArraySize)->getBeginLoc(),
|
||||
diag::err_typecheck_negative_array_size)
|
||||
<< (*ArraySize)->getSourceRange());
|
||||
}
|
||||
|
||||
if (!AllocType->isDependentType()) {
|
||||
unsigned ActiveSizeBits =
|
||||
ConstantArrayType::getNumAddressingBits(Context, AllocType, *Value);
|
||||
if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context))
|
||||
return ExprError(
|
||||
Diag((*ArraySize)->getBeginLoc(), diag::err_array_too_large)
|
||||
<< toString(*Value, 10) << (*ArraySize)->getSourceRange());
|
||||
}
|
||||
|
||||
KnownArraySize = Value->getZExtValue();
|
||||
} else if (TypeIdParens.isValid()) {
|
||||
// Can't have dynamic array size when the type-id is in parentheses.
|
||||
Diag((*ArraySize)->getBeginLoc(), diag::ext_new_paren_array_nonconst)
|
||||
<< (*ArraySize)->getSourceRange()
|
||||
<< FixItHint::CreateRemoval(TypeIdParens.getBegin())
|
||||
<< FixItHint::CreateRemoval(TypeIdParens.getEnd());
|
||||
|
||||
TypeIdParens = SourceRange();
|
||||
}
|
||||
|
||||
// Note that we do *not* convert the argument in any way. It can
|
||||
|
@ -2169,11 +2169,10 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
|
||||
}
|
||||
|
||||
Expr *ArgExpr = (ArgDepMatrix->*GetArgDimensionExpr)();
|
||||
if (!ArgExpr->isValueDependent())
|
||||
if (Optional<llvm::APSInt> ArgConst =
|
||||
ArgExpr->getIntegerConstantExpr(S.Context))
|
||||
if (*ArgConst == *ParamConst)
|
||||
return Sema::TDK_Success;
|
||||
if (Optional<llvm::APSInt> ArgConst =
|
||||
ArgExpr->getIntegerConstantExpr(S.Context))
|
||||
if (*ArgConst == *ParamConst)
|
||||
return Sema::TDK_Success;
|
||||
return Sema::TDK_NonDeducedMismatch;
|
||||
}
|
||||
|
||||
|
@ -7814,7 +7814,7 @@ static bool isPermittedNeonBaseType(QualType &Ty,
|
||||
static bool verifyValidIntegerConstantExpr(Sema &S, const ParsedAttr &Attr,
|
||||
llvm::APSInt &Result) {
|
||||
const auto *AttrExpr = Attr.getArgAsExpr(0);
|
||||
if (!AttrExpr->isTypeDependent() && !AttrExpr->isValueDependent()) {
|
||||
if (!AttrExpr->isTypeDependent()) {
|
||||
if (Optional<llvm::APSInt> Res =
|
||||
AttrExpr->getIntegerConstantExpr(S.Context)) {
|
||||
Result = *Res;
|
||||
|
@ -15,3 +15,13 @@ namespace PR11320 {
|
||||
}
|
||||
void h() { g<int>(0); }
|
||||
}
|
||||
|
||||
// Can pass value dependent integer to atomic builtin
|
||||
template <int Order>
|
||||
void fetchAdd(int *A, int V) {
|
||||
__atomic_fetch_add(A, V, Order);
|
||||
}
|
||||
|
||||
void fetchAddUse(int *A, int V) {
|
||||
fetchAdd<__ATOMIC_ACQ_REL>(A, V);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user