aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Expr.h6
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td12
-rw-r--r--include/clang/Sema/Sema.h20
-rw-r--r--lib/Sema/SemaDecl.cpp42
-rw-r--r--lib/Sema/SemaDeclAttr.cpp11
-rw-r--r--lib/Sema/SemaDeclCXX.cpp12
-rw-r--r--lib/Sema/SemaExpr.cpp106
-rw-r--r--lib/Sema/SemaExprCXX.cpp30
-rw-r--r--lib/Sema/SemaInit.cpp34
-rw-r--r--lib/Sema/SemaOverload.cpp15
-rw-r--r--lib/Sema/SemaStmt.cpp14
-rw-r--r--lib/Sema/SemaTemplate.cpp10
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp13
-rw-r--r--lib/Sema/SemaType.cpp56
-rw-r--r--test/CXX/except/except.spec/p1.cpp2
-rw-r--r--test/CXX/expr/expr.const/p2-0x.cpp28
-rw-r--r--test/Parser/cxx0x-attributes.cpp4
-rw-r--r--test/Sema/i-c-e.c4
-rw-r--r--test/Sema/switch.c7
-rw-r--r--test/SemaCXX/enum-bitfield.cpp2
-rw-r--r--test/SemaCXX/i-c-e-cxx.cpp6
-rw-r--r--test/SemaCXX/new-delete.cpp6
22 files changed, 266 insertions, 174 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 591640d30c..33f95afd32 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -415,6 +415,9 @@ public:
/// constant expression, and, if so, return its value in Result. If not a
/// valid i-c-e, return false and fill in Loc (if specified) with the location
/// of the invalid expression.
+ ///
+ /// Note: This does not perform the implicit conversions required by C++11
+ /// [expr.const]p5.
bool isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
SourceLocation *Loc = 0,
bool isEvaluated = true) const;
@@ -422,6 +425,9 @@ public:
/// isCXX11ConstantExpr - Return true if this expression is a constant
/// expression in C++11. Can only be used in C++.
+ ///
+ /// Note: This does not perform the implicit conversions required by C++11
+ /// [expr.const]p5.
bool isCXX11ConstantExpr(ASTContext &Ctx, APValue *Result = 0,
SourceLocation *Loc = 0) const;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 2138d1de98..7eef491e48 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -31,6 +31,18 @@ def err_cce_narrowing : Error<
"%select{case value|enumerator value|non-type template argument}0 "
"%select{cannot be narrowed from type %2 to %3|"
"evaluates to %2, which cannot be narrowed to type %3}1">;
+def err_ice_not_integral : Error<
+ "integral constant expression must have integral or unscoped enumeration "
+ "type, not %0">;
+def err_ice_incomplete_type : Error<
+ "integral constant expression has incomplete class type %0">;
+def err_ice_explicit_conversion : Error<
+ "integral constant expression requires explicit conversion from %0 to %1">;
+def note_ice_conversion_here : Note<
+ "conversion to %select{integral|enumeration}0 type %1 declared here">;
+def err_ice_ambiguous_conversion : Error<
+ "ambiguous conversion from type %0 to an integral or unscoped "
+ "enumeration type">;
// Semantic analysis of constant literals.
def ext_predef_outside_function : Warning<
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 2069dc9704..c5915ca168 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -6120,17 +6120,25 @@ public:
/// VerifyIntegerConstantExpression - Verifies that an expression is an ICE,
/// and reports the appropriate diagnostics. Returns false on success.
/// Can optionally return the value of the expression.
- bool VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result = 0,
- unsigned DiagId = 0,
- bool AllowFold = true);
+ ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
+ PartialDiagnostic Diag,
+ bool AllowFold,
+ PartialDiagnostic FoldDiag);
+ ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
+ PartialDiagnostic Diag,
+ bool AllowFold = true) {
+ return VerifyIntegerConstantExpression(E, Result, Diag, AllowFold,
+ PDiag(0));
+ }
+ ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result = 0);
/// VerifyBitField - verifies that a bit field expression is an ICE and has
/// the correct width, and that the field type is valid.
/// Returns false on success.
/// Can optionally return whether the bit-field is of width 0
- bool VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
- QualType FieldTy, const Expr *BitWidth,
- bool *ZeroWidth = 0);
+ ExprResult VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
+ QualType FieldTy, Expr *BitWidth,
+ bool *ZeroWidth = 0);
enum CUDAFunctionTarget {
CFT_Device,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 0e5e6781a6..b68591ae93 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -8465,9 +8465,10 @@ void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) {
}
// Note that FieldName may be null for anonymous bitfields.
-bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
- QualType FieldTy, const Expr *BitWidth,
- bool *ZeroWidth) {
+ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
+ IdentifierInfo *FieldName,
+ QualType FieldTy, Expr *BitWidth,
+ bool *ZeroWidth) {
// Default to true; that shouldn't confuse checks for emptiness
if (ZeroWidth)
*ZeroWidth = true;
@@ -8477,7 +8478,7 @@ bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
if (!FieldTy->isDependentType() && !FieldTy->isIntegralOrEnumerationType()) {
// Handle incomplete types with specific error.
if (RequireCompleteType(FieldLoc, FieldTy, diag::err_field_incomplete))
- return true;
+ return ExprError();
if (FieldName)
return Diag(FieldLoc, diag::err_not_integral_type_bitfield)
<< FieldName << FieldTy << BitWidth->getSourceRange();
@@ -8485,16 +8486,18 @@ bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
<< FieldTy << BitWidth->getSourceRange();
} else if (DiagnoseUnexpandedParameterPack(const_cast<Expr *>(BitWidth),
UPPC_BitFieldWidth))
- return true;
+ return ExprError();
// If the bit-width is type- or value-dependent, don't try to check
// it now.
if (BitWidth->isValueDependent() || BitWidth->isTypeDependent())
- return false;
+ return Owned(BitWidth);
llvm::APSInt Value;
- if (VerifyIntegerConstantExpression(BitWidth, &Value))
- return true;
+ ExprResult ICE = VerifyIntegerConstantExpression(BitWidth, &Value);
+ if (ICE.isInvalid())
+ return ICE;
+ BitWidth = ICE.take();
if (Value != 0 && ZeroWidth)
*ZeroWidth = false;
@@ -8534,7 +8537,7 @@ bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
}
}
- return false;
+ return Owned(BitWidth);
}
/// ActOnField - Each field of a C struct/union is passed into this in order
@@ -8700,11 +8703,13 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
bool ZeroWidth = false;
// If this is declared as a bit-field, check the bit-field.
- if (!InvalidDecl && BitWidth &&
- VerifyBitField(Loc, II, T, BitWidth, &ZeroWidth)) {
- InvalidDecl = true;
- BitWidth = 0;
- ZeroWidth = false;
+ if (!InvalidDecl && BitWidth) {
+ BitWidth = VerifyBitField(Loc, II, T, BitWidth, &ZeroWidth).take();
+ if (!BitWidth) {
+ InvalidDecl = true;
+ BitWidth = 0;
+ ZeroWidth = false;
+ }
}
// Check that 'mutable' is consistent with the type of the declaration.
@@ -9027,10 +9032,9 @@ Decl *Sema::ActOnIvar(Scope *S,
if (BitWidth) {
// 6.7.2.1p3, 6.7.2.1p4
- if (VerifyBitField(Loc, II, T, BitWidth)) {
+ BitWidth = VerifyBitField(Loc, II, T, BitWidth).take();
+ if (!BitWidth)
D.setInvalidType();
- BitWidth = 0;
- }
} else {
// Not a bitfield.
@@ -9591,9 +9595,9 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
else
Val = Converted.take();
} else if (!Val->isValueDependent() &&
- VerifyIntegerConstantExpression(Val, &EnumVal)) {
+ !(Val = VerifyIntegerConstantExpression(Val,
+ &EnumVal).take())) {
// C99 6.7.2.2p2: Make sure we have an integer constant expression.
- Val = 0;
} else {
if (!getLangOptions().CPlusPlus) {
// C99 6.7.2.2p2:
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index d1dc0de5cb..54e7969e0d 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -2604,18 +2604,19 @@ void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) {
SourceLocation AttrLoc = AttrRange.getBegin();
// FIXME: Cache the number on the Attr object?
llvm::APSInt Alignment(32);
- if (!E->isIntegerConstantExpr(Alignment, Context)) {
- Diag(AttrLoc, diag::err_attribute_argument_not_int)
- << "aligned" << E->getSourceRange();
+ ExprResult ICE =
+ VerifyIntegerConstantExpression(E, &Alignment,
+ PDiag(diag::err_attribute_argument_not_int) << "aligned",
+ /*AllowFold*/ false);
+ if (ICE.isInvalid())
return;
- }
if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) {
Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two)
<< E->getSourceRange();
return;
}
- D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E));
+ D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take()));
}
void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) {
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 7a648939e0..f36750ba74 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -9918,10 +9918,16 @@ Decl *Sema::ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc,
StringLiteral *AssertMessage = cast<StringLiteral>(AssertMessageExpr_);
if (!AssertExpr->isTypeDependent() && !AssertExpr->isValueDependent()) {
+ // In a static_assert-declaration, the constant-expression shall be a
+ // constant expression that can be contextually converted to bool.
+ ExprResult Converted = PerformContextuallyConvertToBool(AssertExpr);
+ if (Converted.isInvalid())
+ return 0;
+
llvm::APSInt Cond;
- if (VerifyIntegerConstantExpression(AssertExpr, &Cond,
- diag::err_static_assert_expression_is_not_constant,
- /*AllowFold=*/false))
+ if (VerifyIntegerConstantExpression(Converted.get(), &Cond,
+ PDiag(diag::err_static_assert_expression_is_not_constant),
+ /*AllowFold=*/false).isInvalid())
return 0;
if (!Cond)
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 3d8758e94e..3056156951 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -8544,11 +8544,11 @@ ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc,
} else {
// The conditional expression is required to be a constant expression.
llvm::APSInt condEval(32);
- SourceLocation ExpLoc;
- if (!CondExpr->isIntegerConstantExpr(condEval, Context, &ExpLoc))
- return ExprError(Diag(ExpLoc,
- diag::err_typecheck_choose_expr_requires_constant)
- << CondExpr->getSourceRange());
+ ExprResult CondICE = VerifyIntegerConstantExpression(CondExpr, &condEval,
+ PDiag(diag::err_typecheck_choose_expr_requires_constant), false);
+ if (CondICE.isInvalid())
+ return ExprError();
+ CondExpr = CondICE.take();
// If the condition is > zero, then the AST type is the same as the LSHExpr.
Expr *ActiveExpr = condEval.getZExtValue() ? LHSExpr : RHSExpr;
@@ -9120,16 +9120,61 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
return isInvalid;
}
-bool Sema::VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result,
- unsigned DiagID, bool AllowFold) {
+ExprResult Sema::VerifyIntegerConstantExpression(Expr *E,
+ llvm::APSInt *Result) {
+ return VerifyIntegerConstantExpression(E, Result,
+ PDiag(diag::err_expr_not_ice) << LangOpts.CPlusPlus);
+}
+
+ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
+ PartialDiagnostic NotIceDiag,
+ bool AllowFold,
+ PartialDiagnostic FoldDiag) {
+ SourceLocation DiagLoc = E->getSourceRange().getBegin();
+
+ if (getLangOptions().CPlusPlus0x) {
+ // C++11 [expr.const]p5:
+ // If an expression of literal class type is used in a context where an
+ // integral constant expression is required, then that class type shall
+ // have a single non-explicit conversion function to an integral or
+ // unscoped enumeration type
+ ExprResult Converted;
+ if (NotIceDiag.getDiagID()) {
+ Converted = ConvertToIntegralOrEnumerationType(
+ DiagLoc, E,
+ PDiag(diag::err_ice_not_integral),
+ PDiag(diag::err_ice_incomplete_type),
+ PDiag(diag::err_ice_explicit_conversion),
+ PDiag(diag::note_ice_conversion_here),
+ PDiag(diag::err_ice_ambiguous_conversion),
+ PDiag(diag::note_ice_conversion_here),
+ PDiag(0),
+ /*AllowScopedEnumerations*/ false);
+ } else {
+ // The caller wants to silently enquire whether this is an ICE. Don't
+ // produce any diagnostics if it isn't.
+ Converted = ConvertToIntegralOrEnumerationType(
+ DiagLoc, E, PDiag(), PDiag(), PDiag(), PDiag(),
+ PDiag(), PDiag(), PDiag(), false);
+ }
+ if (Converted.isInvalid())
+ return Converted;
+ E = Converted.take();
+ if (!E->getType()->isIntegralOrUnscopedEnumerationType())
+ return ExprError();
+ } else if (!E->getType()->isIntegralOrUnscopedEnumerationType()) {
+ // An ICE must be of integral or unscoped enumeration type.
+ if (NotIceDiag.getDiagID())
+ Diag(DiagLoc, NotIceDiag) << E->getSourceRange();
+ return ExprError();
+ }
+
// Circumvent ICE checking in C++11 to avoid evaluating the expression twice
// in the non-ICE case.
- if (!getLangOptions().CPlusPlus0x) {
- if (E->isIntegerConstantExpr(Context)) {
- if (Result)
- *Result = E->EvaluateKnownConstInt(Context);
- return false;
- }
+ if (!getLangOptions().CPlusPlus0x && E->isIntegerConstantExpr(Context)) {
+ if (Result)
+ *Result = E->EvaluateKnownConstInt(Context);
+ return Owned(E);
}
Expr::EvalResult EvalResult;
@@ -9147,36 +9192,39 @@ bool Sema::VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result,
if (Folded && getLangOptions().CPlusPlus0x && Notes.empty()) {
if (Result)
*Result = EvalResult.Val.getInt();
- return false;
+ return Owned(E);
+ }
+
+ // If our only note is the usual "invalid subexpression" note, just point
+ // the caret at its location rather than producing an essentially
+ // redundant note.
+ if (Notes.size() == 1 && Notes[0].second.getDiagID() ==
+ diag::note_invalid_subexpr_in_const_expr) {
+ DiagLoc = Notes[0].first;
+ Notes.clear();
}
if (!Folded || !AllowFold) {
- if (DiagID)
- Diag(E->getSourceRange().getBegin(), DiagID) << E->getSourceRange();
- else
- Diag(E->getSourceRange().getBegin(), diag::err_expr_not_ice)
- << E->getSourceRange() << LangOpts.CPlusPlus;
-
- // We only show the notes if they're not the usual "invalid subexpression"
- // or if they are actually in a subexpression.
- if (Notes.size() != 1 ||
- Notes[0].second.getDiagID() != diag::note_invalid_subexpr_in_const_expr
- || Notes[0].first != E->IgnoreParens()->getExprLoc()) {
+ if (NotIceDiag.getDiagID()) {
+ Diag(DiagLoc, NotIceDiag) << E->getSourceRange();
for (unsigned I = 0, N = Notes.size(); I != N; ++I)
Diag(Notes[I].first, Notes[I].second);
}
- return true;
+ return ExprError();
}
- Diag(E->getSourceRange().getBegin(), diag::ext_expr_not_ice)
- << E->getSourceRange() << LangOpts.CPlusPlus;
+ if (FoldDiag.getDiagID())
+ Diag(DiagLoc, FoldDiag) << E->getSourceRange();
+ else
+ Diag(DiagLoc, diag::ext_expr_not_ice)
+ << E->getSourceRange() << LangOpts.CPlusPlus;
for (unsigned I = 0, N = Notes.size(); I != N; ++I)
Diag(Notes[I].first, Notes[I].second);
if (Result)
*Result = EvalResult.Val.getInt();
- return false;
+ return Owned(E);
}
namespace {
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 158e02a450..e2a9f83a1f 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -900,11 +900,11 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
DeclaratorChunk::ArrayTypeInfo &Array = D.getTypeObject(I).Arr;
if (Expr *NumElts = (Expr *)Array.NumElts) {
- if (!NumElts->isTypeDependent() && !NumElts->isValueDependent() &&
- !NumElts->isIntegerConstantExpr(Context)) {
- Diag(D.getTypeObject(I).Loc, diag::err_new_array_nonconst)
- << NumElts->getSourceRange();
- return ExprError();
+ if (!NumElts->isTypeDependent() && !NumElts->isValueDependent()) {
+ Array.NumElts = VerifyIntegerConstantExpression(NumElts, 0,
+ PDiag(diag::err_new_array_nonconst)).take();
+ if (!Array.NumElts)
+ return ExprError();
}
}
}
@@ -1034,6 +1034,8 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
// std::bad_array_new_length.
if (!ArraySize->isValueDependent()) {
llvm::APSInt Value;
+ // We've already performed any required implicit conversion to integer or
+ // unscoped enumeration type.
if (ArraySize->isIntegerConstantExpr(Value, Context)) {
if (Value < llvm::APSInt(
llvm::APInt::getNullValue(Value.getBitWidth()),
@@ -3269,18 +3271,16 @@ static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT,
case ATT_ArrayExtent: {
llvm::APSInt Value;
uint64_t Dim;
- if (DimExpr->isIntegerConstantExpr(Value, Self.Context, 0, false)) {
- if (Value < llvm::APSInt(Value.getBitWidth(), Value.isUnsigned())) {
- Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer) <<
- DimExpr->getSourceRange();
- return false;
- }
- Dim = Value.getLimitedValue();
- } else {
- Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer) <<
+ if (Self.VerifyIntegerConstantExpression(DimExpr, &Value,
+ Self.PDiag(diag::err_dimension_expr_not_constant_integer),
+ false).isInvalid())
+ return 0;
+ if (Value.isSigned() && Value.isNegative()) {
+ Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer),
DimExpr->getSourceRange();
- return false;
+ return 0;
}
+ Dim = Value.getLimitedValue();
if (T->isArrayType()) {
unsigned D = 0;
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 096ca7c93b..aa45c8333a 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -2150,26 +2150,27 @@ void InitListChecker::UpdateStructuredListElement(InitListExpr *StructuredList,
}
/// Check that the given Index expression is a valid array designator
-/// value. This is essentailly just a wrapper around
+/// value. This is essentially just a wrapper around
/// VerifyIntegerConstantExpression that also checks for negative values
/// and produces a reasonable diagnostic if there is a
-/// failure. Returns true if there was an error, false otherwise. If
-/// everything went okay, Value will receive the value of the constant
-/// expression.
-static bool
+/// failure. Returns the index expression, possibly with an implicit cast
+/// added, on success. If everything went okay, Value will receive the
+/// value of the constant expression.
+static ExprResult
CheckArrayDesignatorExpr(Sema &S, Expr *Index, llvm::APSInt &Value) {
SourceLocation Loc = Index->getSourceRange().getBegin();
// Make sure this is an integer constant expression.
- if (S.VerifyIntegerConstantExpression(Index, &Value))
- return true;
+ ExprResult Result = S.VerifyIntegerConstantExpression(Index, &Value);
+ if (Result.isInvalid())
+ return Result;
if (Value.isSigned() && Value.isNegative())
return S.Diag(Loc, diag::err_array_designator_negative)
<< Value.toString(10) << Index->getSourceRange();
Value.setIsUnsigned(true);
- return false;
+ return Result;
}
ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
@@ -2194,9 +2195,9 @@ ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
case Designator::ArrayDesignator: {
Expr *Index = static_cast<Expr *>(D.getArrayIndex());
llvm::APSInt IndexValue;
- if (!Index->isTypeDependent() &&
- !Index->isValueDependent() &&
- CheckArrayDesignatorExpr(*this, Index, IndexValue))
+ if (!Index->isTypeDependent() && !Index->isValueDependent())
+ Index = CheckArrayDesignatorExpr(*this, Index, IndexValue).take();
+ if (!Index)
Invalid = true;
else {
Designators.push_back(ASTDesignator(InitExpressions.size(),
@@ -2216,10 +2217,13 @@ ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
StartIndex->isValueDependent();
bool EndDependent = EndIndex->isTypeDependent() ||
EndIndex->isValueDependent();
- if ((!StartDependent &&
- CheckArrayDesignatorExpr(*this, StartIndex, StartValue)) ||
- (!EndDependent &&
- CheckArrayDesignatorExpr(*this, EndIndex, EndValue)))
+ if (!StartDependent)
+ StartIndex =
+ CheckArrayDesignatorExpr(*this, StartIndex, StartValue).take();
+ if (!EndDependent)
+ EndIndex = CheckArrayDesignatorExpr(*this, EndIndex, EndValue).take();
+
+ if (!StartIndex || !EndIndex)
Invalid = true;
else {
// Make sure we're comparing values with the same bit width.
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 9527c0f298..5fe136a166 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -4841,8 +4841,8 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *From,
// expression of integral or enumeration type.
const RecordType *RecordTy = T->getAs<RecordType>();
if (!RecordTy || !getLangOptions().CPlusPlus) {
- Diag(Loc, NotIntDiag)
- << T << From->getSourceRange();
+ if (NotIntDiag.getDiagID())
+ Diag(Loc, NotIntDiag) << T << From->getSourceRange();
return Owned(From);
}
@@ -4877,7 +4877,7 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *From,
switch (ViableConversions.size()) {
case 0:
- if (ExplicitConversions.size() == 1) {
+ if (ExplicitConversions.size() == 1 && ExplicitConvDiag.getDiagID()) {
DeclAccessPair Found = ExplicitConversions[0];
CXXConversionDecl *Conversion
= cast<CXXConversionDecl>(Found->getUnderlyingDecl());
@@ -4948,6 +4948,9 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *From,
}
default:
+ if (!AmbigDiag.getDiagID())
+ return Owned(From);
+
Diag(Loc, AmbigDiag)
<< T << From->getSourceRange();
for (unsigned I = 0, N = ViableConversions.size(); I != N; ++I) {
@@ -4960,9 +4963,9 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *From,
return Owned(From);
}
- if (!isIntegralOrEnumerationType(From->getType(), AllowScopedEnumerations))
- Diag(Loc, NotIntDiag)
- << From->getType() << From->getSourceRange();
+ if (!isIntegralOrEnumerationType(From->getType(), AllowScopedEnumerations) &&
+ NotIntDiag.getDiagID())
+ Diag(Loc, NotIntDiag) << From->getType() << From->getSourceRange();
return DefaultLvalueConversion(From);
}
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 42b608e631..e49bcfada6 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -274,15 +274,17 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,
if (!getLangOptions().CPlusPlus0x) {
// C99 6.8.4.2p3: The expression shall be an integer constant.
// However, GCC allows any evaluatable integer expression.
- if (!LHSVal->isTypeDependent() && !LHSVal->isValueDependent() &&
- VerifyIntegerConstantExpression(LHSVal))
- return StmtError();
+ if (!LHSVal->isTypeDependent() && !LHSVal->isValueDependent()) {
+ LHSVal = VerifyIntegerConstantExpression(LHSVal).take();
+ if (!LHSVal)
+ return StmtError();
+ }
// GCC extension: The expression shall be an integer constant.
- if (RHSVal && !RHSVal->isTypeDependent() && !RHSVal->isValueDependent() &&
- VerifyIntegerConstantExpression(RHSVal)) {
- RHSVal = 0; // Recover by just forgetting about it.
+ if (RHSVal && !RHSVal->isTypeDependent() && !RHSVal->isValueDependent()) {
+ RHSVal = VerifyIntegerConstantExpression(RHSVal).take();
+ // Recover from an error by just forgetting about it.
}
}
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index eca491f733..421e5e2141 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -3912,11 +3912,11 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
<< ArgType << Arg->getSourceRange();
Diag(Param->getLocation(), diag::note_template_param_here);
return ExprError();
- } else if (!Arg->isValueDependent() &&
- !Arg->isIntegerConstantExpr(Value, Context, &NonConstantLoc)) {
- Diag(NonConstantLoc, diag::err_template_arg_not_ice)
- << ArgType << Arg->getSourceRange();
- return ExprError();
+ } else if (!Arg->isValueDependent()) {
+ Arg = VerifyIntegerConstantExpression(Arg, &Value,
+ PDiag(diag::err_template_arg_not_ice) << ArgType, false).take();
+ if (!Arg)
+ return ExprError();
}
// From here on out, all we care about are the unqualified forms
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 023005cd19..a957f25ef2 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2347,17 +2347,12 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
E = SemaRef.CheckBooleanCondition(E.get(), E.get()->getLocStart());
if (E.isUsable()) {
- SourceLocation ErrLoc;
- llvm::APSInt NoexceptVal;
NoexceptExpr = E.take();
if (!NoexceptExpr->isTypeDependent() &&
- !NoexceptExpr->isValueDependent() &&
- !NoexceptExpr->isIntegerConstantExpr(NoexceptVal, SemaRef.Context,
- &ErrLoc, /*evaluated=*/false)){
- SemaRef.Diag(ErrLoc, diag::err_noexcept_needs_constant_expression)
- << NoexceptExpr->getSourceRange();
- NoexceptExpr = 0;
- }
+ !NoexceptExpr->isValueDependent())
+ NoexceptExpr = SemaRef.VerifyIntegerConstantExpression(NoexceptExpr,
+ 0, SemaRef.PDiag(diag::err_noexcept_needs_constant_expression),
+ /*AllowFold*/ false).take();
}
}
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 684f355bfb..d613c395d3 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1178,19 +1178,12 @@ QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue,
/// Check whether the specified array size makes the array type a VLA. If so,
/// return true, if not, return the size of the array in SizeVal.
-static bool isArraySizeVLA(Expr *ArraySize, llvm::APSInt &SizeVal, Sema &S) {
- // If the size is an ICE, it certainly isn't a VLA.
- if (ArraySize->isIntegerConstantExpr(SizeVal, S.Context))
- return false;
-
- // If we're in a GNU mode (like gnu99, but not c99) accept any evaluatable
- // value as an extension.
- if (S.LangOpts.GNUMode && ArraySize->EvaluateAsInt(SizeVal, S.Context)) {
- S.Diag(ArraySize->getLocStart(), diag::ext_vla_folded_to_constant);
- return false;
- }
-
- return true;
+static bool isArraySizeVLA(Sema &S, Expr *ArraySize, llvm::APSInt &SizeVal) {
+ // If the size is an ICE, it certainly isn't a VLA. If we're in a GNU mode
+ // (like gnu99, but not c99) accept any evaluatable value as an extension.
+ return S.VerifyIntegerConstantExpression(
+ ArraySize, &SizeVal, S.PDiag(), S.LangOpts.GNUMode,
+ S.PDiag(diag::ext_vla_folded_to_constant)).isInvalid();
}
@@ -1285,14 +1278,15 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
}
// C99 6.7.5.2p1: The size expression shall have integer type.
- // TODO: in theory, if we were insane, we could allow contextual
- // conversions to integer type here.
- if (ArraySize && !ArraySize->isTypeDependent() &&
+ // C++11 allows contextual conversions to such types.
+ if (!getLangOptions().CPlusPlus0x &&
+ ArraySize && !ArraySize->isTypeDependent() &&
!ArraySize->getType()->isIntegralOrUnscopedEnumerationType()) {
Diag(ArraySize->getLocStart(), diag::err_array_size_non_int)
<< ArraySize->getType() << ArraySize->getSourceRange();
return QualType();
}
+
llvm::APSInt ConstVal(Context.getTypeSize(Context.getSizeType()));
if (!ArraySize) {
if (ASM == ArrayType::Star)
@@ -1301,11 +1295,19 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
T = Context.getIncompleteArrayType(T, ASM, Quals);
} else if (ArraySize->isTypeDependent() || ArraySize->isValueDependent()) {
T = Context.getDependentSizedArrayType(T, ArraySize, ASM, Quals, Brackets);
- } else if (!T->isDependentType() && !T->isIncompleteType() &&
- !T->isConstantSizeType()) {
+ } else if ((!T->isDependentType() && !T->isIncompleteType() &&
+ !T->isConstantSizeType()) ||
+ isArraySizeVLA(*this, ArraySize, ConstVal)) {
+ // Even in C++11, don't allow contextual conversions in the array bound
+ // of a VLA.
+ if (getLangOptions().CPlusPlus0x &&
+ !ArraySize->getType()->isIntegralOrUnscopedEnumerationType()) {
+ Diag(ArraySize->getLocStart(), diag::err_array_size_non_int)
+ << ArraySize->getType() << ArraySize->getSourceRange();
+ return QualType();
+ }
+
// C99: an array with an element type that has a non-constant-size is a VLA.
- T = Context.getVariableArrayType(T, ArraySize, ASM, Quals, Brackets);
- } else if (isArraySizeVLA(ArraySize, ConstVal, *this)) {
// C99: an array with a non-ICE size is a VLA. We accept any expression
// that we can fold to a non-zero positive value as an extension.
T = Context.getVariableArrayType(T, ArraySize, ASM, Quals, Brackets);
@@ -2283,15 +2285,11 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
NoexceptExpr->getType()->getCanonicalTypeUnqualified() ==
Context.BoolTy) &&
"Parser should have made sure that the expression is boolean");
- SourceLocation ErrLoc;
- llvm::APSInt Dummy;
- if (!NoexceptExpr->isValueDependent() &&
- !NoexceptExpr->isIntegerConstantExpr(Dummy, Context, &ErrLoc,
- /*evaluated*/false))
- S.Diag(ErrLoc, diag::err_noexcept_needs_constant_expression)
- <