|
@@ -4376,10 +4376,11 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc,
|
|
return ExprError();
|
|
return ExprError();
|
|
|
|
|
|
if (LowerBound && !OriginalTy->isAnyPointerType()) {
|
|
if (LowerBound && !OriginalTy->isAnyPointerType()) {
|
|
- llvm::APSInt LowerBoundValue;
|
|
|
|
- if (LowerBound->EvaluateAsInt(LowerBoundValue, Context)) {
|
|
|
|
|
|
+ Expr::EvalResult Result;
|
|
|
|
+ if (LowerBound->EvaluateAsInt(Result, Context)) {
|
|
// OpenMP 4.5, [2.4 Array Sections]
|
|
// OpenMP 4.5, [2.4 Array Sections]
|
|
// The array section must be a subset of the original array.
|
|
// The array section must be a subset of the original array.
|
|
|
|
+ llvm::APSInt LowerBoundValue = Result.Val.getInt();
|
|
if (LowerBoundValue.isNegative()) {
|
|
if (LowerBoundValue.isNegative()) {
|
|
Diag(LowerBound->getExprLoc(), diag::err_omp_section_not_subset_of_array)
|
|
Diag(LowerBound->getExprLoc(), diag::err_omp_section_not_subset_of_array)
|
|
<< LowerBound->getSourceRange();
|
|
<< LowerBound->getSourceRange();
|
|
@@ -4389,10 +4390,11 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc,
|
|
}
|
|
}
|
|
|
|
|
|
if (Length) {
|
|
if (Length) {
|
|
- llvm::APSInt LengthValue;
|
|
|
|
- if (Length->EvaluateAsInt(LengthValue, Context)) {
|
|
|
|
|
|
+ Expr::EvalResult Result;
|
|
|
|
+ if (Length->EvaluateAsInt(Result, Context)) {
|
|
// OpenMP 4.5, [2.4 Array Sections]
|
|
// OpenMP 4.5, [2.4 Array Sections]
|
|
// The length must evaluate to non-negative integers.
|
|
// The length must evaluate to non-negative integers.
|
|
|
|
+ llvm::APSInt LengthValue = Result.Val.getInt();
|
|
if (LengthValue.isNegative()) {
|
|
if (LengthValue.isNegative()) {
|
|
Diag(Length->getExprLoc(), diag::err_omp_section_length_negative)
|
|
Diag(Length->getExprLoc(), diag::err_omp_section_length_negative)
|
|
<< LengthValue.toString(/*Radix=*/10, /*Signed=*/true)
|
|
<< LengthValue.toString(/*Radix=*/10, /*Signed=*/true)
|
|
@@ -5799,6 +5801,13 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
|
|
? VK_RValue
|
|
? VK_RValue
|
|
: VK_LValue;
|
|
: VK_LValue;
|
|
|
|
|
|
|
|
+ if (isFileScope)
|
|
|
|
+ if (auto ILE = dyn_cast<InitListExpr>(LiteralExpr))
|
|
|
|
+ for (unsigned i = 0, j = ILE->getNumInits(); i != j; i++) {
|
|
|
|
+ Expr *Init = ILE->getInit(i);
|
|
|
|
+ ILE->setInit(i, ConstantExpr::Create(Context, Init));
|
|
|
|
+ }
|
|
|
|
+
|
|
Expr *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType,
|
|
Expr *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType,
|
|
VK, LiteralExpr, isFileScope);
|
|
VK, LiteralExpr, isFileScope);
|
|
if (isFileScope) {
|
|
if (isFileScope) {
|
|
@@ -5807,7 +5816,6 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
|
|
!literalType->isDependentType()) // C99 6.5.2.5p3
|
|
!literalType->isDependentType()) // C99 6.5.2.5p3
|
|
if (CheckForConstantInitializer(LiteralExpr, literalType))
|
|
if (CheckForConstantInitializer(LiteralExpr, literalType))
|
|
return ExprError();
|
|
return ExprError();
|
|
- E = new (Context) ConstantExpr(E);
|
|
|
|
} else if (literalType.getAddressSpace() != LangAS::opencl_private &&
|
|
} else if (literalType.getAddressSpace() != LangAS::opencl_private &&
|
|
literalType.getAddressSpace() != LangAS::Default) {
|
|
literalType.getAddressSpace() != LangAS::Default) {
|
|
// Embedded-C extensions to C99 6.5.2.5:
|
|
// Embedded-C extensions to C99 6.5.2.5:
|
|
@@ -8403,8 +8411,8 @@ static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int,
|
|
// Reject cases where the value of the Int is unknown as that would
|
|
// Reject cases where the value of the Int is unknown as that would
|
|
// possibly cause truncation, but accept cases where the scalar can be
|
|
// possibly cause truncation, but accept cases where the scalar can be
|
|
// demoted without loss of precision.
|
|
// demoted without loss of precision.
|
|
- llvm::APSInt Result;
|
|
|
|
- bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context);
|
|
|
|
|
|
+ Expr::EvalResult EVResult;
|
|
|
|
+ bool CstInt = Int->get()->EvaluateAsInt(EVResult, S.Context);
|
|
int Order = S.Context.getIntegerTypeOrder(OtherIntTy, IntTy);
|
|
int Order = S.Context.getIntegerTypeOrder(OtherIntTy, IntTy);
|
|
bool IntSigned = IntTy->hasSignedIntegerRepresentation();
|
|
bool IntSigned = IntTy->hasSignedIntegerRepresentation();
|
|
bool OtherIntSigned = OtherIntTy->hasSignedIntegerRepresentation();
|
|
bool OtherIntSigned = OtherIntTy->hasSignedIntegerRepresentation();
|
|
@@ -8412,6 +8420,7 @@ static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int,
|
|
if (CstInt) {
|
|
if (CstInt) {
|
|
// If the scalar is constant and is of a higher order and has more active
|
|
// If the scalar is constant and is of a higher order and has more active
|
|
// bits that the vector element type, reject it.
|
|
// bits that the vector element type, reject it.
|
|
|
|
+ llvm::APSInt Result = EVResult.Val.getInt();
|
|
unsigned NumBits = IntSigned
|
|
unsigned NumBits = IntSigned
|
|
? (Result.isNegative() ? Result.getMinSignedBits()
|
|
? (Result.isNegative() ? Result.getMinSignedBits()
|
|
: Result.getActiveBits())
|
|
: Result.getActiveBits())
|
|
@@ -8439,8 +8448,9 @@ static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int,
|
|
|
|
|
|
// Determine if the integer constant can be expressed as a floating point
|
|
// Determine if the integer constant can be expressed as a floating point
|
|
// number of the appropriate type.
|
|
// number of the appropriate type.
|
|
- llvm::APSInt Result;
|
|
|
|
- bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context);
|
|
|
|
|
|
+ Expr::EvalResult EVResult;
|
|
|
|
+ bool CstInt = Int->get()->EvaluateAsInt(EVResult, S.Context);
|
|
|
|
+
|
|
uint64_t Bits = 0;
|
|
uint64_t Bits = 0;
|
|
if (CstInt) {
|
|
if (CstInt) {
|
|
// Reject constants that would be truncated if they were converted to
|
|
// Reject constants that would be truncated if they were converted to
|
|
@@ -8448,6 +8458,7 @@ static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int,
|
|
// FIXME: Ideally the conversion to an APFloat and from an APFloat
|
|
// FIXME: Ideally the conversion to an APFloat and from an APFloat
|
|
// could be avoided if there was a convertFromAPInt method
|
|
// could be avoided if there was a convertFromAPInt method
|
|
// which could signal back if implicit truncation occurred.
|
|
// which could signal back if implicit truncation occurred.
|
|
|
|
+ llvm::APSInt Result = EVResult.Val.getInt();
|
|
llvm::APFloat Float(S.Context.getFloatTypeSemantics(FloatTy));
|
|
llvm::APFloat Float(S.Context.getFloatTypeSemantics(FloatTy));
|
|
Float.convertFromAPInt(Result, IntTy->hasSignedIntegerRepresentation(),
|
|
Float.convertFromAPInt(Result, IntTy->hasSignedIntegerRepresentation(),
|
|
llvm::APFloat::rmTowardZero);
|
|
llvm::APFloat::rmTowardZero);
|
|
@@ -8787,9 +8798,10 @@ static void DiagnoseBadDivideOrRemainderValues(Sema& S, ExprResult &LHS,
|
|
ExprResult &RHS,
|
|
ExprResult &RHS,
|
|
SourceLocation Loc, bool IsDiv) {
|
|
SourceLocation Loc, bool IsDiv) {
|
|
// Check for division/remainder by zero.
|
|
// Check for division/remainder by zero.
|
|
- llvm::APSInt RHSValue;
|
|
|
|
|
|
+ Expr::EvalResult RHSValue;
|
|
if (!RHS.get()->isValueDependent() &&
|
|
if (!RHS.get()->isValueDependent() &&
|
|
- RHS.get()->EvaluateAsInt(RHSValue, S.Context) && RHSValue == 0)
|
|
|
|
|
|
+ RHS.get()->EvaluateAsInt(RHSValue, S.Context) &&
|
|
|
|
+ RHSValue.Val.getInt() == 0)
|
|
S.DiagRuntimeBehavior(Loc, RHS.get(),
|
|
S.DiagRuntimeBehavior(Loc, RHS.get(),
|
|
S.PDiag(diag::warn_remainder_division_by_zero)
|
|
S.PDiag(diag::warn_remainder_division_by_zero)
|
|
<< IsDiv << RHS.get()->getSourceRange());
|
|
<< IsDiv << RHS.get()->getSourceRange());
|
|
@@ -9031,8 +9043,9 @@ static void diagnoseStringPlusInt(Sema &Self, SourceLocation OpLoc,
|
|
if (!IsStringPlusInt || IndexExpr->isValueDependent())
|
|
if (!IsStringPlusInt || IndexExpr->isValueDependent())
|
|
return;
|
|
return;
|
|
|
|
|
|
- llvm::APSInt index;
|
|
|
|
- if (IndexExpr->EvaluateAsInt(index, Self.getASTContext())) {
|
|
|
|
|
|
+ Expr::EvalResult Result;
|
|
|
|
+ if (IndexExpr->EvaluateAsInt(Result, Self.getASTContext())) {
|
|
|
|
+ llvm::APSInt index = Result.Val.getInt();
|
|
unsigned StrLenWithNull = StrExpr->getLength() + 1;
|
|
unsigned StrLenWithNull = StrExpr->getLength() + 1;
|
|
if (index.isNonNegative() &&
|
|
if (index.isNonNegative() &&
|
|
index <= llvm::APSInt(llvm::APInt(index.getBitWidth(), StrLenWithNull),
|
|
index <= llvm::APSInt(llvm::APInt(index.getBitWidth(), StrLenWithNull),
|
|
@@ -9176,10 +9189,11 @@ QualType Sema::CheckAdditionOperands(ExprResult &LHS, ExprResult &RHS,
|
|
if (PExp->IgnoreParenCasts()->isNullPointerConstant(
|
|
if (PExp->IgnoreParenCasts()->isNullPointerConstant(
|
|
Context, Expr::NPC_ValueDependentIsNotNull)) {
|
|
Context, Expr::NPC_ValueDependentIsNotNull)) {
|
|
// In C++ adding zero to a null pointer is defined.
|
|
// In C++ adding zero to a null pointer is defined.
|
|
- llvm::APSInt KnownVal;
|
|
|
|
|
|
+ Expr::EvalResult KnownVal;
|
|
if (!getLangOpts().CPlusPlus ||
|
|
if (!getLangOpts().CPlusPlus ||
|
|
(!IExp->isValueDependent() &&
|
|
(!IExp->isValueDependent() &&
|
|
- (!IExp->EvaluateAsInt(KnownVal, Context) || KnownVal != 0))) {
|
|
|
|
|
|
+ (!IExp->EvaluateAsInt(KnownVal, Context) ||
|
|
|
|
+ KnownVal.Val.getInt() != 0))) {
|
|
// Check the conditions to see if this is the 'p = nullptr + n' idiom.
|
|
// Check the conditions to see if this is the 'p = nullptr + n' idiom.
|
|
bool IsGNUIdiom = BinaryOperator::isNullPointerArithmeticExtension(
|
|
bool IsGNUIdiom = BinaryOperator::isNullPointerArithmeticExtension(
|
|
Context, BO_Add, PExp, IExp);
|
|
Context, BO_Add, PExp, IExp);
|
|
@@ -9254,10 +9268,11 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
|
|
if (LHS.get()->IgnoreParenCasts()->isNullPointerConstant(Context,
|
|
if (LHS.get()->IgnoreParenCasts()->isNullPointerConstant(Context,
|
|
Expr::NPC_ValueDependentIsNotNull)) {
|
|
Expr::NPC_ValueDependentIsNotNull)) {
|
|
// In C++ adding zero to a null pointer is defined.
|
|
// In C++ adding zero to a null pointer is defined.
|
|
- llvm::APSInt KnownVal;
|
|
|
|
|
|
+ Expr::EvalResult KnownVal;
|
|
if (!getLangOpts().CPlusPlus ||
|
|
if (!getLangOpts().CPlusPlus ||
|
|
(!RHS.get()->isValueDependent() &&
|
|
(!RHS.get()->isValueDependent() &&
|
|
- (!RHS.get()->EvaluateAsInt(KnownVal, Context) || KnownVal != 0))) {
|
|
|
|
|
|
+ (!RHS.get()->EvaluateAsInt(KnownVal, Context) ||
|
|
|
|
+ KnownVal.Val.getInt() != 0))) {
|
|
diagnoseArithmeticOnNullPointer(*this, Loc, LHS.get(), false);
|
|
diagnoseArithmeticOnNullPointer(*this, Loc, LHS.get(), false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -9333,11 +9348,12 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
|
|
if (S.getLangOpts().OpenCL)
|
|
if (S.getLangOpts().OpenCL)
|
|
return;
|
|
return;
|
|
|
|
|
|
- llvm::APSInt Right;
|
|
|
|
// Check right/shifter operand
|
|
// Check right/shifter operand
|
|
|
|
+ Expr::EvalResult RHSResult;
|
|
if (RHS.get()->isValueDependent() ||
|
|
if (RHS.get()->isValueDependent() ||
|
|
- !RHS.get()->EvaluateAsInt(Right, S.Context))
|
|
|
|
|
|
+ !RHS.get()->EvaluateAsInt(RHSResult, S.Context))
|
|
return;
|
|
return;
|
|
|
|
+ llvm::APSInt Right = RHSResult.Val.getInt();
|
|
|
|
|
|
if (Right.isNegative()) {
|
|
if (Right.isNegative()) {
|
|
S.DiagRuntimeBehavior(Loc, RHS.get(),
|
|
S.DiagRuntimeBehavior(Loc, RHS.get(),
|
|
@@ -9360,11 +9376,12 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
|
|
// according to C++ has undefined behavior ([expr.shift] 5.8/2). Unsigned
|
|
// according to C++ has undefined behavior ([expr.shift] 5.8/2). Unsigned
|
|
// integers have defined behavior modulo one more than the maximum value
|
|
// integers have defined behavior modulo one more than the maximum value
|
|
// representable in the result type, so never warn for those.
|
|
// representable in the result type, so never warn for those.
|
|
- llvm::APSInt Left;
|
|
|
|
|
|
+ Expr::EvalResult LHSResult;
|
|
if (LHS.get()->isValueDependent() ||
|
|
if (LHS.get()->isValueDependent() ||
|
|
LHSType->hasUnsignedIntegerRepresentation() ||
|
|
LHSType->hasUnsignedIntegerRepresentation() ||
|
|
- !LHS.get()->EvaluateAsInt(Left, S.Context))
|
|
|
|
|
|
+ !LHS.get()->EvaluateAsInt(LHSResult, S.Context))
|
|
return;
|
|
return;
|
|
|
|
+ llvm::APSInt Left = LHSResult.Val.getInt();
|
|
|
|
|
|
// If LHS does not have a signed type and non-negative value
|
|
// If LHS does not have a signed type and non-negative value
|
|
// then, the behavior is undefined. Warn about it.
|
|
// then, the behavior is undefined. Warn about it.
|
|
@@ -10734,8 +10751,9 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
|
|
// that isn't 0 or 1 (which indicate a potential logical operation that
|
|
// that isn't 0 or 1 (which indicate a potential logical operation that
|
|
// happened to fold to true/false) then warn.
|
|
// happened to fold to true/false) then warn.
|
|
// Parens on the RHS are ignored.
|
|
// Parens on the RHS are ignored.
|
|
- llvm::APSInt Result;
|
|
|
|
- if (RHS.get()->EvaluateAsInt(Result, Context))
|
|
|
|
|
|
+ Expr::EvalResult EVResult;
|
|
|
|
+ if (RHS.get()->EvaluateAsInt(EVResult, Context)) {
|
|
|
|
+ llvm::APSInt Result = EVResult.Val.getInt();
|
|
if ((getLangOpts().Bool && !RHS.get()->getType()->isBooleanType() &&
|
|
if ((getLangOpts().Bool && !RHS.get()->getType()->isBooleanType() &&
|
|
!RHS.get()->getExprLoc().isMacroID()) ||
|
|
!RHS.get()->getExprLoc().isMacroID()) ||
|
|
(Result != 0 && Result != 1)) {
|
|
(Result != 0 && Result != 1)) {
|
|
@@ -10755,6 +10773,7 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
|
|
SourceRange(getLocForEndOfToken(LHS.get()->getEndLoc()),
|
|
SourceRange(getLocForEndOfToken(LHS.get()->getEndLoc()),
|
|
RHS.get()->getEndLoc()));
|
|
RHS.get()->getEndLoc()));
|
|
}
|
|
}
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
if (!Context.getLangOpts().CPlusPlus) {
|
|
if (!Context.getLangOpts().CPlusPlus) {
|
|
@@ -14170,12 +14189,15 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
|
|
return ExprError();
|
|
return ExprError();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (!isa<ConstantExpr>(E))
|
|
|
|
+ E = ConstantExpr::Create(Context, E);
|
|
|
|
+
|
|
// Circumvent ICE checking in C++11 to avoid evaluating the expression twice
|
|
// Circumvent ICE checking in C++11 to avoid evaluating the expression twice
|
|
// in the non-ICE case.
|
|
// in the non-ICE case.
|
|
if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) {
|
|
if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) {
|
|
if (Result)
|
|
if (Result)
|
|
*Result = E->EvaluateKnownConstIntCheckOverflow(Context);
|
|
*Result = E->EvaluateKnownConstIntCheckOverflow(Context);
|
|
- return new (Context) ConstantExpr(E);
|
|
|
|
|
|
+ return E;
|
|
}
|
|
}
|
|
|
|
|
|
Expr::EvalResult EvalResult;
|
|
Expr::EvalResult EvalResult;
|
|
@@ -14193,7 +14215,7 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
|
|
if (Folded && getLangOpts().CPlusPlus11 && Notes.empty()) {
|
|
if (Folded && getLangOpts().CPlusPlus11 && Notes.empty()) {
|
|
if (Result)
|
|
if (Result)
|
|
*Result = EvalResult.Val.getInt();
|
|
*Result = EvalResult.Val.getInt();
|
|
- return new (Context) ConstantExpr(E);
|
|
|
|
|
|
+ return E;
|
|
}
|
|
}
|
|
|
|
|
|
// If our only note is the usual "invalid subexpression" note, just point
|
|
// If our only note is the usual "invalid subexpression" note, just point
|
|
@@ -14221,7 +14243,7 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
|
|
|
|
|
|
if (Result)
|
|
if (Result)
|
|
*Result = EvalResult.Val.getInt();
|
|
*Result = EvalResult.Val.getInt();
|
|
- return new (Context) ConstantExpr(E);
|
|
|
|
|
|
+ return E;
|
|
}
|
|
}
|
|
|
|
|
|
namespace {
|
|
namespace {
|