mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 19:06:05 +00:00
Revert "Following up on PR48517, fix handling of template arguments that refer"
This reverts commit 8c1f2d15b826591cdf6bd6b468b8a7d23377b29e. This is part of 5 commits being reverted due to https://crbug.com/1161059. See bug for repro.
This commit is contained in:
parent
2080232333
commit
af0dbaaa38
@ -578,12 +578,12 @@ public:
|
||||
struct EvalStatus {
|
||||
/// Whether the evaluated expression has side effects.
|
||||
/// For example, (f() && 0) can be folded, but it still has side effects.
|
||||
bool HasSideEffects = false;
|
||||
bool HasSideEffects;
|
||||
|
||||
/// Whether the evaluation hit undefined behavior.
|
||||
/// For example, 1.0 / 0.0 can be folded to Inf, but has undefined behavior.
|
||||
/// Likewise, INT_MAX + 1 can be folded to INT_MIN, but has UB.
|
||||
bool HasUndefinedBehavior = false;
|
||||
bool HasUndefinedBehavior;
|
||||
|
||||
/// Diag - If this is non-null, it will be filled in with a stack of notes
|
||||
/// indicating why evaluation failed (or why it failed to produce a constant
|
||||
@ -592,7 +592,10 @@ public:
|
||||
/// foldable. If the expression is foldable, but not a constant expression,
|
||||
/// the notes will describes why it isn't a constant expression. If the
|
||||
/// expression *is* a constant expression, no notes will be produced.
|
||||
SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr;
|
||||
SmallVectorImpl<PartialDiagnosticAt> *Diag;
|
||||
|
||||
EvalStatus()
|
||||
: HasSideEffects(false), HasUndefinedBehavior(false), Diag(nullptr) {}
|
||||
|
||||
// hasSideEffects - Return true if the evaluated expression has
|
||||
// side effects.
|
||||
@ -603,11 +606,8 @@ public:
|
||||
|
||||
/// EvalResult is a struct with detailed info about an evaluated expression.
|
||||
struct EvalResult : EvalStatus {
|
||||
/// This is the value the expression can be folded to.
|
||||
/// Val - This is the value the expression can be folded to.
|
||||
APValue Val;
|
||||
/// Indicates whether Val contains a pointer or reference or pointer to
|
||||
/// member naming a templated entity, and thus the value is dependent.
|
||||
bool Dependent = false;
|
||||
|
||||
// isGlobalLValue - Return true if the evaluated lvalue expression
|
||||
// is global.
|
||||
|
@ -252,12 +252,6 @@ public:
|
||||
/// Whether this template argument is dependent on a template
|
||||
/// parameter such that its result can change from one instantiation to
|
||||
/// another.
|
||||
///
|
||||
/// It's not always meaningful to ask whether a template argument is
|
||||
/// dependent before it's been converted to match a template parameter;
|
||||
/// whether a non-type template argument is dependent depends on the
|
||||
/// corresponding parameter. For an unconverted template argument, this
|
||||
/// returns true if the argument *might* be dependent.
|
||||
bool isDependent() const;
|
||||
|
||||
/// Whether this template argument is dependent on a template
|
||||
@ -680,6 +674,13 @@ struct alignas(void *) ASTTemplateKWAndArgsInfo {
|
||||
void initializeFrom(SourceLocation TemplateKWLoc,
|
||||
const TemplateArgumentListInfo &List,
|
||||
TemplateArgumentLoc *OutArgArray);
|
||||
// FIXME: The parameter Deps is the result populated by this method, the
|
||||
// caller doesn't need it since it is populated by computeDependence. remove
|
||||
// it.
|
||||
void initializeFrom(SourceLocation TemplateKWLoc,
|
||||
const TemplateArgumentListInfo &List,
|
||||
TemplateArgumentLoc *OutArgArray,
|
||||
TemplateArgumentDependence &Deps);
|
||||
void initializeFrom(SourceLocation TemplateKWLoc);
|
||||
|
||||
void copyInto(const TemplateArgumentLoc *ArgArray,
|
||||
|
@ -3353,8 +3353,7 @@ public:
|
||||
llvm::APSInt &Value, CCEKind CCE);
|
||||
ExprResult CheckConvertedConstantExpression(Expr *From, QualType T,
|
||||
APValue &Value, CCEKind CCE,
|
||||
NamedDecl *Dest = nullptr,
|
||||
bool *ValueDependent = nullptr);
|
||||
NamedDecl *Dest = nullptr);
|
||||
|
||||
/// Abstract base class used to perform a contextual implicit
|
||||
/// conversion from an expression to any type passing a filter.
|
||||
|
@ -64,7 +64,7 @@ ExprDependence clang::computeDependence(UnaryOperator *E,
|
||||
if (VD && VD->isTemplated()) {
|
||||
auto *VarD = dyn_cast<VarDecl>(VD);
|
||||
if (!VarD || !VarD->hasLocalStorage())
|
||||
Dep |= ExprDependence::ValueInstantiation;
|
||||
Dep |= ExprDependence::Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -443,21 +443,12 @@ ExprDependence clang::computeDependence(DeclRefExpr *E, const ASTContext &Ctx) {
|
||||
if (auto *FirstArg = E->getTemplateArgs()) {
|
||||
unsigned NumArgs = E->getNumTemplateArgs();
|
||||
for (auto *Arg = FirstArg, *End = FirstArg + NumArgs; Arg < End; ++Arg)
|
||||
Deps |= toExprDependence(Arg->getArgument().getDependence() &
|
||||
~TemplateArgumentDependence::Dependent);
|
||||
Deps |= toExprDependence(Arg->getArgument().getDependence());
|
||||
}
|
||||
|
||||
auto *Decl = E->getDecl();
|
||||
auto *Found = E->getFoundDecl();
|
||||
auto Type = E->getType();
|
||||
|
||||
// FIXME: For a ParmVarDecl referenced in a function signature, we don't know
|
||||
// its dependence yet!
|
||||
if (!isa<ParmVarDecl>(Decl)) {
|
||||
if (Decl->getDeclContext()->isDependentContext() ||
|
||||
(Found && Found->getDeclContext()->isDependentContext()))
|
||||
Deps |= ExprDependence::Instantiation;
|
||||
}
|
||||
if (Decl->isParameterPack())
|
||||
Deps |= ExprDependence::UnexpandedPack;
|
||||
Deps |= toExprDependence(Type->getDependence()) & ExprDependence::Error;
|
||||
|
@ -416,9 +416,12 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
|
||||
RefersToEnclosingVariableOrCapture;
|
||||
DeclRefExprBits.NonOdrUseReason = NOUR;
|
||||
if (TemplateArgs) {
|
||||
auto Deps = TemplateArgumentDependence::None;
|
||||
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
|
||||
TemplateKWLoc, *TemplateArgs,
|
||||
getTrailingObjects<TemplateArgumentLoc>());
|
||||
TemplateKWLoc, *TemplateArgs, getTrailingObjects<TemplateArgumentLoc>(),
|
||||
Deps);
|
||||
assert(!(Deps & TemplateArgumentDependence::Dependent) &&
|
||||
"built a DeclRefExpr with dependent template args");
|
||||
} else if (TemplateKWLoc.isValid()) {
|
||||
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
|
||||
TemplateKWLoc);
|
||||
@ -1521,8 +1524,16 @@ MemberExpr *MemberExpr::Create(
|
||||
MemberExpr *E = new (Mem) MemberExpr(Base, IsArrow, OperatorLoc, MemberDecl,
|
||||
NameInfo, T, VK, OK, NOUR);
|
||||
|
||||
// FIXME: Move this into the constructor.
|
||||
// FIXME: remove remaining dependence computation to computeDependence().
|
||||
auto Deps = E->getDependence();
|
||||
if (HasQualOrFound) {
|
||||
// FIXME: Wrong. We should be looking at the member declaration we found.
|
||||
if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isDependent())
|
||||
Deps |= ExprDependence::TypeValueInstantiation;
|
||||
else if (QualifierLoc &&
|
||||
QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())
|
||||
Deps |= ExprDependence::Instantiation;
|
||||
|
||||
E->MemberExprBits.HasQualifierOrFoundDecl = true;
|
||||
|
||||
MemberExprNameQualifier *NQ =
|
||||
@ -1535,26 +1546,16 @@ MemberExpr *MemberExpr::Create(
|
||||
TemplateArgs || TemplateKWLoc.isValid();
|
||||
|
||||
if (TemplateArgs) {
|
||||
auto TemplateArgDeps = TemplateArgumentDependence::None;
|
||||
E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
|
||||
TemplateKWLoc, *TemplateArgs,
|
||||
E->getTrailingObjects<TemplateArgumentLoc>());
|
||||
E->getTrailingObjects<TemplateArgumentLoc>(), TemplateArgDeps);
|
||||
if (TemplateArgDeps & TemplateArgumentDependence::Instantiation)
|
||||
Deps |= ExprDependence::Instantiation;
|
||||
} else if (TemplateKWLoc.isValid()) {
|
||||
E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
|
||||
TemplateKWLoc);
|
||||
}
|
||||
|
||||
// FIXME: remove remaining dependence computation to computeDependence().
|
||||
auto Deps = E->getDependence();
|
||||
if (NestedNameSpecifier *Qual = E->getQualifier()) {
|
||||
// FIXME: Wrong. We should be looking at the member declaration we found.
|
||||
if (Qual->isDependent())
|
||||
Deps |= ExprDependence::TypeValueInstantiation;
|
||||
else if (Qual->isInstantiationDependent())
|
||||
Deps |= ExprDependence::Instantiation;
|
||||
}
|
||||
if (TemplateSpecializationType::anyInstantiationDependentTemplateArguments(
|
||||
E->template_arguments()))
|
||||
Deps |= ExprDependence::Instantiation;
|
||||
E->setDependence(Deps);
|
||||
|
||||
return E;
|
||||
|
@ -433,8 +433,9 @@ OverloadExpr::OverloadExpr(StmtClass SC, const ASTContext &Context,
|
||||
}
|
||||
|
||||
if (TemplateArgs) {
|
||||
auto Deps = TemplateArgumentDependence::None;
|
||||
getTrailingASTTemplateKWAndArgsInfo()->initializeFrom(
|
||||
TemplateKWLoc, *TemplateArgs, getTrailingTemplateArgumentLoc());
|
||||
TemplateKWLoc, *TemplateArgs, getTrailingTemplateArgumentLoc(), Deps);
|
||||
} else if (TemplateKWLoc.isValid()) {
|
||||
getTrailingASTTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc);
|
||||
}
|
||||
@ -463,8 +464,9 @@ DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(
|
||||
DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo =
|
||||
(Args != nullptr) || TemplateKWLoc.isValid();
|
||||
if (Args) {
|
||||
auto Deps = TemplateArgumentDependence::None;
|
||||
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
|
||||
TemplateKWLoc, *Args, getTrailingObjects<TemplateArgumentLoc>());
|
||||
TemplateKWLoc, *Args, getTrailingObjects<TemplateArgumentLoc>(), Deps);
|
||||
} else if (TemplateKWLoc.isValid()) {
|
||||
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
|
||||
TemplateKWLoc);
|
||||
@ -1374,9 +1376,10 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(
|
||||
CXXDependentScopeMemberExprBits.OperatorLoc = OperatorLoc;
|
||||
|
||||
if (TemplateArgs) {
|
||||
auto Deps = TemplateArgumentDependence::None;
|
||||
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
|
||||
TemplateKWLoc, *TemplateArgs,
|
||||
getTrailingObjects<TemplateArgumentLoc>());
|
||||
TemplateKWLoc, *TemplateArgs, getTrailingObjects<TemplateArgumentLoc>(),
|
||||
Deps);
|
||||
} else if (TemplateKWLoc.isValid()) {
|
||||
getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
|
||||
TemplateKWLoc);
|
||||
|
@ -1819,8 +1819,7 @@ static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
|
||||
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info);
|
||||
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result,
|
||||
EvalInfo &Info);
|
||||
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result,
|
||||
bool &Dependent);
|
||||
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result);
|
||||
|
||||
/// Evaluate an integer or fixed point expression into an APResult.
|
||||
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result,
|
||||
@ -2108,8 +2107,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
|
||||
QualType Type, const APValue &Value,
|
||||
ConstantExprKind Kind,
|
||||
SourceLocation SubobjectLoc,
|
||||
CheckedTemporaries &CheckedTemps,
|
||||
bool &Dependent);
|
||||
CheckedTemporaries &CheckedTemps);
|
||||
|
||||
/// Check that this reference or pointer core constant expression is a valid
|
||||
/// value for an address or reference constant expression. Return true if we
|
||||
@ -2117,8 +2115,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
|
||||
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
|
||||
QualType Type, const LValue &LVal,
|
||||
ConstantExprKind Kind,
|
||||
CheckedTemporaries &CheckedTemps,
|
||||
bool &Dependent) {
|
||||
CheckedTemporaries &CheckedTemps) {
|
||||
bool IsReferenceType = Type->isReferenceType();
|
||||
|
||||
APValue::LValueBase Base = LVal.getLValueBase();
|
||||
@ -2203,8 +2200,6 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
|
||||
}
|
||||
|
||||
if (BaseVD) {
|
||||
Dependent |= BaseVD->isTemplated();
|
||||
|
||||
if (const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
|
||||
// Check if this is a thread-local variable.
|
||||
if (Var->getTLSKind())
|
||||
@ -2235,9 +2230,6 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
|
||||
}
|
||||
} else if (const auto *MTE =
|
||||
dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
|
||||
if (auto *Extending = MTE->getExtendingDecl())
|
||||
Dependent |= Extending->isTemplated();
|
||||
|
||||
if (CheckedTemps.insert(MTE).second) {
|
||||
QualType TempType = getType(Base);
|
||||
if (TempType.isDestructedType()) {
|
||||
@ -2250,8 +2242,8 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
|
||||
APValue *V = MTE->getOrCreateValue(false);
|
||||
assert(V && "evasluation result refers to uninitialised temporary");
|
||||
if (!CheckEvaluationResult(CheckEvaluationResultKind::ConstantExpression,
|
||||
Info, MTE->getExprLoc(), TempType, *V, Kind,
|
||||
SourceLocation(), CheckedTemps, Dependent))
|
||||
Info, MTE->getExprLoc(), TempType, *V,
|
||||
Kind, SourceLocation(), CheckedTemps))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2280,15 +2272,13 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
|
||||
|
||||
/// Member pointers are constant expressions unless they point to a
|
||||
/// non-virtual dllimport member function.
|
||||
static bool
|
||||
CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc,
|
||||
QualType Type, const APValue &Value,
|
||||
ConstantExprKind Kind, bool &Dependent) {
|
||||
static bool CheckMemberPointerConstantExpression(EvalInfo &Info,
|
||||
SourceLocation Loc,
|
||||
QualType Type,
|
||||
const APValue &Value,
|
||||
ConstantExprKind Kind) {
|
||||
const ValueDecl *Member = Value.getMemberPointerDecl();
|
||||
if (!Member)
|
||||
return true;
|
||||
Dependent |= Member->isTemplated();
|
||||
const auto *FD = dyn_cast<CXXMethodDecl>(Member);
|
||||
const auto *FD = dyn_cast_or_null<CXXMethodDecl>(Member);
|
||||
if (!FD)
|
||||
return true;
|
||||
if (FD->isConsteval()) {
|
||||
@ -2337,8 +2327,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
|
||||
QualType Type, const APValue &Value,
|
||||
ConstantExprKind Kind,
|
||||
SourceLocation SubobjectLoc,
|
||||
CheckedTemporaries &CheckedTemps,
|
||||
bool &Dependent) {
|
||||
CheckedTemporaries &CheckedTemps) {
|
||||
if (!Value.hasValue()) {
|
||||
Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
|
||||
<< true << Type;
|
||||
@ -2360,20 +2349,20 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
|
||||
for (unsigned I = 0, N = Value.getArrayInitializedElts(); I != N; ++I) {
|
||||
if (!CheckEvaluationResult(CERK, Info, DiagLoc, EltTy,
|
||||
Value.getArrayInitializedElt(I), Kind,
|
||||
SubobjectLoc, CheckedTemps, Dependent))
|
||||
SubobjectLoc, CheckedTemps))
|
||||
return false;
|
||||
}
|
||||
if (!Value.hasArrayFiller())
|
||||
return true;
|
||||
return CheckEvaluationResult(CERK, Info, DiagLoc, EltTy,
|
||||
Value.getArrayFiller(), Kind, SubobjectLoc,
|
||||
CheckedTemps, Dependent);
|
||||
CheckedTemps);
|
||||
}
|
||||
if (Value.isUnion() && Value.getUnionField()) {
|
||||
return CheckEvaluationResult(
|
||||
CERK, Info, DiagLoc, Value.getUnionField()->getType(),
|
||||
Value.getUnionValue(), Kind, Value.getUnionField()->getLocation(),
|
||||
CheckedTemps, Dependent);
|
||||
CheckedTemps);
|
||||
}
|
||||
if (Value.isStruct()) {
|
||||
RecordDecl *RD = Type->castAs<RecordType>()->getDecl();
|
||||
@ -2382,7 +2371,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
|
||||
for (const CXXBaseSpecifier &BS : CD->bases()) {
|
||||
if (!CheckEvaluationResult(CERK, Info, DiagLoc, BS.getType(),
|
||||
Value.getStructBase(BaseIndex), Kind,
|
||||
BS.getBeginLoc(), CheckedTemps, Dependent))
|
||||
BS.getBeginLoc(), CheckedTemps))
|
||||
return false;
|
||||
++BaseIndex;
|
||||
}
|
||||
@ -2392,8 +2381,8 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
|
||||
continue;
|
||||
|
||||
if (!CheckEvaluationResult(CERK, Info, DiagLoc, I->getType(),
|
||||
Value.getStructField(I->getFieldIndex()), Kind,
|
||||
I->getLocation(), CheckedTemps, Dependent))
|
||||
Value.getStructField(I->getFieldIndex()),
|
||||
Kind, I->getLocation(), CheckedTemps))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2403,13 +2392,12 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
|
||||
LValue LVal;
|
||||
LVal.setFrom(Info.Ctx, Value);
|
||||
return CheckLValueConstantExpression(Info, DiagLoc, Type, LVal, Kind,
|
||||
CheckedTemps, Dependent);
|
||||
CheckedTemps);
|
||||
}
|
||||
|
||||
if (Value.isMemberPointer() &&
|
||||
CERK == CheckEvaluationResultKind::ConstantExpression)
|
||||
return CheckMemberPointerConstantExpression(Info, DiagLoc, Type, Value,
|
||||
Kind, Dependent);
|
||||
return CheckMemberPointerConstantExpression(Info, DiagLoc, Type, Value, Kind);
|
||||
|
||||
// Everything else is fine.
|
||||
return true;
|
||||
@ -2420,7 +2408,7 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
|
||||
/// check that the expression is of literal type.
|
||||
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc,
|
||||
QualType Type, const APValue &Value,
|
||||
ConstantExprKind Kind, bool &Dependent) {
|
||||
ConstantExprKind Kind) {
|
||||
// Nothing to check for a constant expression of type 'cv void'.
|
||||
if (Type->isVoidType())
|
||||
return true;
|
||||
@ -2428,18 +2416,17 @@ static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc,
|
||||
CheckedTemporaries CheckedTemps;
|
||||
return CheckEvaluationResult(CheckEvaluationResultKind::ConstantExpression,
|
||||
Info, DiagLoc, Type, Value, Kind,
|
||||
SourceLocation(), CheckedTemps, Dependent);
|
||||
SourceLocation(), CheckedTemps);
|
||||
}
|
||||
|
||||
/// Check that this evaluated value is fully-initialized and can be loaded by
|
||||
/// an lvalue-to-rvalue conversion.
|
||||
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc,
|
||||
QualType Type, const APValue &Value) {
|
||||
bool Dependent = false;
|
||||
CheckedTemporaries CheckedTemps;
|
||||
return CheckEvaluationResult(
|
||||
CheckEvaluationResultKind::FullyInitialized, Info, DiagLoc, Type, Value,
|
||||
ConstantExprKind::Normal, SourceLocation(), CheckedTemps, Dependent);
|
||||
ConstantExprKind::Normal, SourceLocation(), CheckedTemps);
|
||||
}
|
||||
|
||||
/// Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless
|
||||
@ -11111,9 +11098,7 @@ static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg) {
|
||||
ArgType->isAnyComplexType() || ArgType->isPointerType() ||
|
||||
ArgType->isNullPtrType()) {
|
||||
APValue V;
|
||||
bool Dependent = false;
|
||||
if (!::EvaluateAsRValue(Info, Arg, V, Dependent) ||
|
||||
Info.EvalStatus.HasSideEffects) {
|
||||
if (!::EvaluateAsRValue(Info, Arg, V) || Info.EvalStatus.HasSideEffects) {
|
||||
Fold.keepDiagnostics();
|
||||
return false;
|
||||
}
|
||||
@ -11415,8 +11400,7 @@ static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type,
|
||||
// It's possible for us to be given GLValues if we're called via
|
||||
// Expr::tryEvaluateObjectSize.
|
||||
APValue RVal;
|
||||
bool Dependent = false;
|
||||
if (!EvaluateAsRValue(Info, E, RVal, Dependent))
|
||||
if (!EvaluateAsRValue(Info, E, RVal))
|
||||
return false;
|
||||
LVal.setFrom(Info.Ctx, RVal);
|
||||
} else if (!EvaluatePointer(ignorePointerCastsAndParens(E), LVal, Info,
|
||||
@ -12845,9 +12829,8 @@ bool RecordExprEvaluator::VisitBinCmp(const BinaryOperator *E) {
|
||||
LV.set(VD);
|
||||
if (!handleLValueToRValueConversion(Info, E, E->getType(), LV, Result))
|
||||
return false;
|
||||
bool Dependent = false;
|
||||
return CheckConstantExpression(Info, E->getExprLoc(), E->getType(), Result,
|
||||
ConstantExprKind::Normal, Dependent);
|
||||
ConstantExprKind::Normal);
|
||||
};
|
||||
return EvaluateComparisonBinaryOperator(Info, E, OnSuccess, [&]() {
|
||||
return ExprEvaluatorBaseTy::VisitBinCmp(E);
|
||||
@ -14611,8 +14594,7 @@ static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This,
|
||||
|
||||
/// EvaluateAsRValue - Try to evaluate this expression, performing an implicit
|
||||
/// lvalue-to-rvalue cast if it is an lvalue.
|
||||
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result,
|
||||
bool &Dependent) {
|
||||
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result) {
|
||||
assert(!E->isValueDependent());
|
||||
if (Info.EnableNewConstInterp) {
|
||||
if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E, Result))
|
||||
@ -14637,7 +14619,7 @@ static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result,
|
||||
|
||||
// Check this core constant expression is a constant expression.
|
||||
return CheckConstantExpression(Info, E->getExprLoc(), E->getType(), Result,
|
||||
ConstantExprKind::Normal, Dependent) &&
|
||||
ConstantExprKind::Normal) &&
|
||||
CheckMemoryLeaks(Info);
|
||||
}
|
||||
|
||||
@ -14683,7 +14665,7 @@ static bool EvaluateAsRValue(const Expr *E, Expr::EvalResult &Result,
|
||||
if (FastEvaluateAsRValue(E, Result, Ctx, IsConst))
|
||||
return IsConst;
|
||||
|
||||
return EvaluateAsRValue(Info, E, Result.Val, Result.Dependent);
|
||||
return EvaluateAsRValue(Info, E, Result.Val);
|
||||
}
|
||||
|
||||
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult,
|
||||
@ -14793,9 +14775,9 @@ bool Expr::EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx,
|
||||
CheckedTemporaries CheckedTemps;
|
||||
if (!EvaluateLValue(this, LV, Info) || !Info.discardCleanups() ||
|
||||
Result.HasSideEffects ||
|
||||
!CheckLValueConstantExpression(
|
||||
Info, getExprLoc(), Ctx.getLValueReferenceType(getType()), LV,
|
||||
ConstantExprKind::Normal, CheckedTemps, Result.Dependent))
|
||||
!CheckLValueConstantExpression(Info, getExprLoc(),
|
||||
Ctx.getLValueReferenceType(getType()), LV,
|
||||
ConstantExprKind::Normal, CheckedTemps))
|
||||
return false;
|
||||
|
||||
LV.moveInto(Result.Val);
|
||||
@ -14854,7 +14836,7 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx,
|
||||
llvm_unreachable("Unhandled cleanup; missing full expression marker?");
|
||||
|
||||
if (!CheckConstantExpression(Info, getExprLoc(), getStorageType(Ctx, this),
|
||||
Result.Val, Kind, Result.Dependent))
|
||||
Result.Val, Kind))
|
||||
return false;
|
||||
if (!CheckMemoryLeaks(Info))
|
||||
return false;
|
||||
@ -14918,9 +14900,8 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
|
||||
if (!Info.discardCleanups())
|
||||
llvm_unreachable("Unhandled cleanup; missing full expression marker?");
|
||||
}
|
||||
bool Dependent = false;
|
||||
return CheckConstantExpression(Info, DeclLoc, DeclTy, Value,
|
||||
ConstantExprKind::Normal, Dependent) &&
|
||||
ConstantExprKind::Normal) &&
|
||||
CheckMemoryLeaks(Info);
|
||||
}
|
||||
|
||||
@ -14987,7 +14968,7 @@ APSInt Expr::EvaluateKnownConstIntCheckOverflow(
|
||||
Info.InConstantContext = true;
|
||||
Info.CheckingForUndefinedBehavior = true;
|
||||
|
||||
bool Result = ::EvaluateAsRValue(this, EVResult, Ctx, Info);
|
||||
bool Result = ::EvaluateAsRValue(Info, this, EVResult.Val);
|
||||
(void)Result;
|
||||
assert(Result && "Could not evaluate expression");
|
||||
assert(EVResult.Val.isInt() && "Expression did not evaluate to integer");
|
||||
@ -14999,10 +14980,13 @@ void Expr::EvaluateForOverflow(const ASTContext &Ctx) const {
|
||||
assert(!isValueDependent() &&
|
||||
"Expression evaluator can't be called on a dependent expression.");
|
||||
|
||||
bool IsConst;
|
||||
EvalResult EVResult;
|
||||
EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
|
||||
Info.CheckingForUndefinedBehavior = true;
|
||||
(void)::EvaluateAsRValue(this, EVResult, Ctx, Info);
|
||||
if (!FastEvaluateAsRValue(this, EVResult, Ctx, IsConst)) {
|
||||
EvalInfo Info(Ctx, EVResult, EvalInfo::EM_IgnoreSideEffects);
|
||||
Info.CheckingForUndefinedBehavior = true;
|
||||
(void)::EvaluateAsRValue(Info, this, EVResult.Val);
|
||||
}
|
||||
}
|
||||
|
||||
bool Expr::EvalResult::isGlobalLValue() const {
|
||||
@ -15552,9 +15536,8 @@ bool Expr::isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result,
|
||||
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
|
||||
|
||||
APValue Scratch;
|
||||
bool Dependent = false;
|
||||
bool IsConstExpr =
|
||||
::EvaluateAsRValue(Info, this, Result ? *Result : Scratch, Dependent) &&
|
||||
::EvaluateAsRValue(Info, this, Result ? *Result : Scratch) &&
|
||||
// FIXME: We don't produce a diagnostic for this, but the callers that
|
||||
// call us on arbitrary full-expressions should generally not care.
|
||||
Info.discardCleanups() && !Status.HasSideEffects;
|
||||
|
@ -131,17 +131,25 @@ TemplateArgumentDependence TemplateArgument::getDependence() const {
|
||||
return TemplateArgumentDependence::Dependent |
|
||||
TemplateArgumentDependence::Instantiation;
|
||||
|
||||
case Declaration: {
|
||||
auto *DC = dyn_cast<DeclContext>(getAsDecl());
|
||||
if (!DC)
|
||||
DC = getAsDecl()->getDeclContext();
|
||||
if (DC->isDependentContext())
|
||||
Deps = TemplateArgumentDependence::Dependent |
|
||||
TemplateArgumentDependence::Instantiation;
|
||||
return Deps;
|
||||
}
|
||||
|
||||
case NullPtr:
|
||||
case Integral:
|
||||
case Declaration:
|
||||
return TemplateArgumentDependence::None;
|
||||
|
||||
case Expression:
|
||||
Deps = toTemplateArgumentDependence(getAsExpr()->getDependence());
|
||||
// Instantiation-dependent expression arguments are considered dependent
|
||||
// until they're resolved to another form.
|
||||
if (Deps & TemplateArgumentDependence::Instantiation)
|
||||
Deps |= TemplateArgumentDependence::Dependent;
|
||||
if (isa<PackExpansionExpr>(getAsExpr()))
|
||||
Deps |= TemplateArgumentDependence::Dependent |
|
||||
TemplateArgumentDependence::Instantiation;
|
||||
return Deps;
|
||||
|
||||
case Pack:
|
||||
@ -536,8 +544,8 @@ ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
|
||||
NumTemplateArgs = Info.size();
|
||||
|
||||
TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
|
||||
std::uninitialized_copy(Info.arguments().begin(), Info.arguments().end(),
|
||||
ArgBuffer);
|
||||
for (unsigned i = 0; i != NumTemplateArgs; ++i)
|
||||
new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
|
||||
}
|
||||
|
||||
void ASTTemplateKWAndArgsInfo::initializeFrom(
|
||||
@ -547,8 +555,9 @@ void ASTTemplateKWAndArgsInfo::initializeFrom(
|
||||
LAngleLoc = Info.getLAngleLoc();
|
||||
RAngleLoc = Info.getRAngleLoc();
|
||||
NumTemplateArgs = Info.size();
|
||||
std::uninitialized_copy(Info.arguments().begin(), Info.arguments().end(),
|
||||
OutArgArray);
|
||||
|
||||
for (unsigned i = 0; i != NumTemplateArgs; ++i)
|
||||
new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
|
||||
}
|
||||
|
||||
void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
|
||||
@ -559,6 +568,21 @@ void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
|
||||
NumTemplateArgs = 0;
|
||||
}
|
||||
|
||||
void ASTTemplateKWAndArgsInfo::initializeFrom(
|
||||
SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
|
||||
TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
|
||||
this->TemplateKWLoc = TemplateKWLoc;
|
||||
LAngleLoc = Info.getLAngleLoc();
|
||||
RAngleLoc = Info.getRAngleLoc();
|
||||
NumTemplateArgs = Info.size();
|
||||
|
||||
for (unsigned i = 0; i != NumTemplateArgs; ++i) {
|
||||
Deps |= Info[i].getArgument().getDependence();
|
||||
|
||||
new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
|
||||
TemplateArgumentListInfo &Info) const {
|
||||
Info.setLAngleLoc(LAngleLoc);
|
||||
|
@ -5619,8 +5619,7 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,
|
||||
QualType T, APValue &Value,
|
||||
Sema::CCEKind CCE,
|
||||
bool RequireInt,
|
||||
NamedDecl *Dest,
|
||||
bool *ValueDependent) {
|
||||
NamedDecl *Dest) {
|
||||
assert(S.getLangOpts().CPlusPlus11 &&
|
||||
"converted constant expression outside C++11");
|
||||
|
||||
@ -5744,8 +5743,6 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,
|
||||
|
||||
if (Result.get()->isValueDependent()) {
|
||||
Value = APValue();
|
||||
if (ValueDependent)
|
||||
*ValueDependent = true;
|
||||
return Result;
|
||||
}
|
||||
|
||||
@ -5769,8 +5766,6 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,
|
||||
Result = ExprError();
|
||||
} else {
|
||||
Value = Eval.Val;
|
||||
if (ValueDependent)
|
||||
*ValueDependent = Eval.Dependent;
|
||||
|
||||
if (Notes.empty()) {
|
||||
// It's a constant expression.
|
||||
@ -5801,10 +5796,9 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,
|
||||
|
||||
ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
|
||||
APValue &Value, CCEKind CCE,
|
||||
NamedDecl *Dest,
|
||||
bool *ValueDependent) {
|
||||
NamedDecl *Dest) {
|
||||
return ::CheckConvertedConstantExpression(*this, From, T, Value, CCE, false,
|
||||
Dest, ValueDependent);
|
||||
Dest);
|
||||
}
|
||||
|
||||
ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
|
||||
@ -5814,8 +5808,7 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
|
||||
|
||||
APValue V;
|
||||
auto R = ::CheckConvertedConstantExpression(*this, From, T, V, CCE, true,
|
||||
/*Dest=*/nullptr,
|
||||
/*ValueDependent=*/nullptr);
|
||||
/*Dest=*/nullptr);
|
||||
if (!R.isInvalid() && !R.get()->isValueDependent())
|
||||
Value = V.getInt();
|
||||
return R;
|
||||
|
@ -6620,12 +6620,6 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S,
|
||||
Arg, ArgType))
|
||||
return true;
|
||||
|
||||
// Don't build a resolved template argument naming a dependent declaration.
|
||||
if (Entity->isTemplated()) {
|
||||
Converted = TemplateArgument(ArgIn);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the template argument.
|
||||
Converted = TemplateArgument(cast<ValueDecl>(Entity->getCanonicalDecl()),
|
||||
S.Context.getCanonicalType(ParamType));
|
||||
@ -6640,6 +6634,8 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,
|
||||
QualType ParamType,
|
||||
Expr *&ResultArg,
|
||||
TemplateArgument &Converted) {
|
||||
bool Invalid = false;
|
||||
|
||||
Expr *Arg = ResultArg;
|
||||
bool ObjCLifetimeConversion;
|
||||
|
||||
@ -6655,7 +6651,7 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,
|
||||
// See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#773
|
||||
bool ExtraParens = false;
|
||||
while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) {
|
||||
if (!ExtraParens) {
|
||||
if (!Invalid && !ExtraParens) {
|
||||
S.Diag(Arg->getBeginLoc(),
|
||||
S.getLangOpts().CPlusPlus11
|
||||
? diag::warn_cxx98_compat_template_arg_extra_parens
|
||||
@ -6684,8 +6680,13 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,
|
||||
ValueDecl *VD = DRE->getDecl();
|
||||
if (VD->getType()->isMemberPointerType()) {
|
||||
if (isa<NonTypeTemplateParmDecl>(VD)) {
|
||||
Converted = TemplateArgument(Arg);
|
||||
return false;
|
||||
if (Arg->isTypeDependent() || Arg->isValueDependent()) {
|
||||
Converted = TemplateArgument(Arg);
|
||||
} else {
|
||||
VD = cast<ValueDecl>(VD->getCanonicalDecl());
|
||||
Converted = TemplateArgument(VD, ParamType);
|
||||
}
|
||||
return Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6744,7 +6745,7 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,
|
||||
ValueDecl *D = cast<ValueDecl>(DRE->getDecl()->getCanonicalDecl());
|
||||
Converted = TemplateArgument(D, S.Context.getCanonicalType(ParamType));
|
||||
}
|
||||
return false;
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
// We found something else, but we don't know specifically what it is.
|
||||
@ -6921,17 +6922,14 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
|
||||
// A template-argument for a non-type template parameter shall be
|
||||
// a converted constant expression of the type of the template-parameter.
|
||||
APValue Value;
|
||||
bool ValueDependent = false;
|
||||
ExprResult ArgResult = CheckConvertedConstantExpression(
|
||||
Arg, ParamType, Value, CCEK_TemplateArg, Param, &ValueDependent);
|
||||
Arg, ParamType, Value, CCEK_TemplateArg, Param);
|
||||
if (ArgResult.isInvalid())
|
||||
return ExprError();
|
||||
|
||||
// For a value-dependent argument, CheckConvertedConstantExpression is
|
||||
// permitted (and expected) to be unable to determine a value. We might find
|
||||
// the evaluated result refers to a dependent declaration even though the
|
||||
// template argument is not a value-dependent expression.
|
||||
if (ValueDependent) {
|
||||
// permitted (and expected) to be unable to determine a value.
|
||||
if (ArgResult.get()->isValueDependent()) {
|
||||
Converted = TemplateArgument(ArgResult.get());
|
||||
return ArgResult;
|
||||
}
|
||||
|
@ -3227,8 +3227,7 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
|
||||
if (FunctionDecl *Pattern =
|
||||
Function->getInstantiatedFromMemberFunction()) {
|
||||
|
||||
if (TSK != TSK_ImplicitInstantiation &&
|
||||
Function->hasAttr<ExcludeFromExplicitInstantiationAttr>())
|
||||
if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>())
|
||||
continue;
|
||||
|
||||
MemberSpecializationInfo *MSInfo =
|
||||
@ -3273,8 +3272,7 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
|
||||
continue;
|
||||
|
||||
if (Var->isStaticDataMember()) {
|
||||
if (TSK != TSK_ImplicitInstantiation &&
|
||||
Var->hasAttr<ExcludeFromExplicitInstantiationAttr>())
|
||||
if (Var->hasAttr<ExcludeFromExplicitInstantiationAttr>())
|
||||
continue;
|
||||
|
||||
MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
|
||||
@ -3291,7 +3289,7 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
|
||||
SuppressNew)
|
||||
continue;
|
||||
|
||||
if (TSK != TSK_ExplicitInstantiationDeclaration) {
|
||||
if (TSK == TSK_ExplicitInstantiationDefinition) {
|
||||
// C++0x [temp.explicit]p8:
|
||||
// An explicit instantiation definition that names a class template
|
||||
// specialization explicitly instantiates the class template
|
||||
|
@ -35,7 +35,7 @@ T tmain(T argc) {
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
#pragma omp distribute dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
#pragma omp distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
return T();
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ T tmain(T argc) {
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
#pragma omp target
|
||||
#pragma omp teams
|
||||
#pragma omp distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
return T();
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ T tmain(T argc) {
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
#pragma omp target
|
||||
#pragma omp teams
|
||||
#pragma omp distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
return T();
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ T tmain(T argc) {
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
#pragma omp target
|
||||
#pragma omp teams
|
||||
#pragma omp distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
return T();
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ T tmain(T argc, S **argv) {
|
||||
#pragma omp target parallel for simd collapse (S) // expected-error {{'S' does not refer to a value}}
|
||||
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
|
||||
|
||||
// expected-error@+1 1+{{integral constant expression}} expected-note@+1 0+{{constant expression}}
|
||||
// expected-error@+1 {{integral constant expression}} expected-note@+1 0+{{constant expression}}
|
||||
#pragma omp target parallel for simd collapse (j=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
|
||||
#pragma omp target parallel for simd collapse (1)
|
||||
|
@ -56,7 +56,7 @@ T tmain(T argc, S **argv) {
|
||||
for (int i = ST; i < N; i++)
|
||||
argv[0][i] = argv[0][i] - argv[0][i - ST];
|
||||
|
||||
// expected-error@+1 {{'ordered' clause with a parameter can not be specified in '#pragma omp target parallel for simd' directive}}
|
||||
// expected-error@+1 {{integral constant expression}} expected-note@+1 0+{{constant expression}}
|
||||
#pragma omp target parallel for simd ordered(j = 2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (int i = ST; i < N; i++)
|
||||
argv[0][i] = argv[0][i] - argv[0][i - ST];
|
||||
|
@ -44,7 +44,7 @@ T tmain(T argc, S **argv) {
|
||||
#pragma omp target simd collapse (S) // expected-error {{'S' does not refer to a value}}
|
||||
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
|
||||
|
||||
// expected-error@+1 1+{{integral constant expression}} expected-note@+1 0+{{constant expression}}
|
||||
// expected-error@+1 {{integral constant expression}} expected-note@+1 0+{{constant expression}}
|
||||
#pragma omp target simd collapse (j=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
|
||||
#pragma omp target simd collapse (1)
|
||||
|
@ -45,7 +45,7 @@ T tmain(T argc) {
|
||||
#pragma omp target teams distribute dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
|
||||
#pragma omp target teams distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp target teams distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
|
||||
return T();
|
||||
|
@ -45,7 +45,7 @@ T tmain(T argc) {
|
||||
#pragma omp target teams distribute parallel for dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
|
||||
#pragma omp target teams distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp target teams distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
|
||||
return T();
|
||||
|
@ -45,7 +45,7 @@ T tmain(T argc) {
|
||||
#pragma omp target teams distribute parallel for simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
|
||||
#pragma omp target teams distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp target teams distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
|
||||
return T();
|
||||
|
@ -45,7 +45,7 @@ T tmain(T argc) {
|
||||
#pragma omp target teams distribute simd dist_schedule (static, S1) // expected-error {{'S1' does not refer to a value}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
|
||||
#pragma omp target teams distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp target teams distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
|
||||
return T();
|
||||
|
@ -131,7 +131,7 @@ T tmain(T argc) {
|
||||
#pragma omp target update from(x, s7.s6[:5].aa[6]) // expected-error {{OpenMP array section is not allowed here}}
|
||||
#pragma omp target update from(x, s7.s6[:5].aa[:6]) // expected-error {{OpenMP array section is not allowed here}}
|
||||
#pragma omp target update from(s7.p[:10])
|
||||
#pragma omp target update from(x, s7.bfa) // expected-error 2{{bit fields cannot be used to specify storage in a 'from' clause}}
|
||||
#pragma omp target update from(x, s7.bfa) // expected-error {{bit fields cannot be used to specify storage in a 'from' clause}}
|
||||
#pragma omp target update from(x, s7.p[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
|
||||
#pragma omp target data map(to: s7.i)
|
||||
{
|
||||
|
@ -138,7 +138,7 @@ T tmain(T argc) {
|
||||
#pragma omp target update to(x, s7.s6[:5].aa[6]) // expected-error {{OpenMP array section is not allowed here}}
|
||||
#pragma omp target update to(x, s7.s6[:5].aa[:6]) // expected-error {{OpenMP array section is not allowed here}}
|
||||
#pragma omp target update to(s7.p[:10])
|
||||
#pragma omp target update to(x, s7.bfa) // expected-error 2{{bit fields cannot be used to specify storage in a 'to' clause}}
|
||||
#pragma omp target update to(x, s7.bfa) // expected-error {{bit fields cannot be used to specify storage in a 'to' clause}}
|
||||
#pragma omp target update to(x, s7.p[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}}
|
||||
#pragma omp target data map(to: s7.i)
|
||||
{
|
||||
|
@ -156,11 +156,11 @@ int foo() {
|
||||
#pragma omp task detach(a) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} omp50-error {{expected variable of the 'omp_event_handle_t' type, not 'int'}} omp50-error {{expected variable of the 'omp_event_handle_t' type, not 'S'}}
|
||||
;
|
||||
#pragma omp task detach(evt) detach(evt) // omp45-error 2 {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} expected-error {{directive '#pragma omp task' cannot contain more than one 'detach' clause}}
|
||||
#pragma omp task detach(cevt) detach(revt) // omp45-error 2 {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} expected-error {{directive '#pragma omp task' cannot contain more than one 'detach' clause}}
|
||||
#pragma omp task detach(cevt) detach(revt) // omp45-error 2 {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} expected-error {{directive '#pragma omp task' cannot contain more than one 'detach' clause}} omp50-error {{expected variable of the 'omp_event_handle_t' type, not 'const omp_event_handle_t' (aka 'const unsigned long')}} omp50-error {{expected variable of the 'omp_event_handle_t' type, not 'omp_event_handle_t &' (aka 'unsigned long &')}}
|
||||
#pragma omp task detach(evt) mergeable // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} omp50-error {{'mergeable' and 'detach' clause are mutually exclusive and may not appear on the same directive}} omp50-note {{'detach' clause is specified here}}
|
||||
;
|
||||
#pragma omp task mergeable detach(evt) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} omp50-error {{'detach' and 'mergeable' clause are mutually exclusive and may not appear on the same directive}} omp50-note {{'mergeable' clause is specified here}}
|
||||
#pragma omp task detach(-evt) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}}
|
||||
#pragma omp task detach(-evt) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}} omp50-error {{expected variable of the 'omp_event_handle_t' type}}
|
||||
;
|
||||
#pragma omp task detach(evt) shared(evt) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}}
|
||||
#pragma omp task detach(evt) firstprivate(evt) // omp45-error {{unexpected OpenMP clause 'detach' in directive '#pragma omp task'}}
|
||||
|
@ -55,7 +55,7 @@ T tmain(T argc) {
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
|
||||
#pragma omp target
|
||||
#pragma omp teams distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp teams distribute dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
|
||||
return T();
|
||||
|
@ -55,7 +55,7 @@ T tmain(T argc) {
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
|
||||
#pragma omp target
|
||||
#pragma omp teams distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp teams distribute parallel for dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
|
||||
return T();
|
||||
|
@ -55,7 +55,7 @@ T tmain(T argc) {
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
|
||||
#pragma omp target
|
||||
#pragma omp teams distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp teams distribute parallel for simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
|
||||
return T();
|
||||
|
@ -55,7 +55,7 @@ T tmain(T argc) {
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
|
||||
#pragma omp target
|
||||
#pragma omp teams distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2{{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp teams distribute simd dist_schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error3 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
for (int i = 0; i < 10; ++i) foo();
|
||||
|
||||
return T();
|
||||
|
@ -147,7 +147,7 @@ void test_templated() {
|
||||
|
||||
auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
|
||||
auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
|
||||
auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
|
||||
auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not used}}
|
||||
auto explicit_by_value_unused_const = [k] { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
|
||||
auto explicit_by_value_unused_const_generic = [k](auto c) { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
|
||||
|
||||
|
@ -503,13 +503,3 @@ namespace PR48517 {
|
||||
template<> struct Q<&R<int>::n> { static constexpr int X = 1; };
|
||||
static_assert(R<int>().f() == 1);
|
||||
}
|
||||
|
||||
namespace dependent_reference {
|
||||
template<int &r> struct S { int *q = &r; };
|
||||
template<int> auto f() { static int n; return S<n>(); }
|
||||
auto v = f<0>();
|
||||
auto w = f<1>();
|
||||
static_assert(!is_same<decltype(v), decltype(w)>);
|
||||
// Ensure that we can instantiate the definition of S<...>.
|
||||
int n = *v.q + *w.q;
|
||||
}
|
@ -292,47 +292,3 @@ namespace Predefined {
|
||||
Y<B{__func__[0]}>(); // expected-error {{reference to subobject of predefined '__func__' variable}}
|
||||
}
|
||||
}
|
||||
|
||||
namespace dependent {
|
||||
template<auto &V> struct R { static inline auto &v = V; };
|
||||
template<auto &V, auto &W> constexpr bool operator==(R<V>, R<W>) { return &V == &W; }
|
||||
template<auto *V> struct S { static inline auto *v = V; };
|
||||
template<auto *V, auto *W> constexpr bool operator==(S<V>, S<W>) { return V == W; }
|
||||
template<auto V> struct T { static inline const auto &v = V; };
|
||||
template<auto V, auto W> constexpr bool operator==(T<V>, T<W>) { return &V == &W; }
|
||||
template<typename T> struct V { T v; };
|
||||
template<int N> auto f() {
|
||||
static int n;
|
||||
static V<int> vn;
|
||||
if constexpr (N < 10)
|
||||
return R<n>();
|
||||
else if constexpr (N < 20)
|
||||
return R<vn.v>(); // FIXME: expected-error 2{{refers to subobject}}
|
||||
else if constexpr (N < 30)
|
||||
return S<&n>();
|
||||
else if constexpr (N < 40)
|
||||
return S<&vn.v>(); // FIXME: expected-error 2{{refers to subobject}}
|
||||
else if constexpr (N < 50)
|
||||
return T<V<int&>{n}>();
|
||||
else if constexpr (N < 60)
|
||||
return T<V<int*>{&n}>();
|
||||
else if constexpr (N < 70)
|
||||
return T<V<int&>{vn.v}>();
|
||||
else if constexpr (N < 80)
|
||||
return T<V<int*>{&vn.v}>();
|
||||
}
|
||||
template<int Base> void check() {
|
||||
auto v = f<Base + 0>(); // FIXME: expected-note 2{{instantiation of}}
|
||||
auto w = f<Base + 1>(); // FIXME: expected-note 2{{instantiation of}}
|
||||
static_assert(!__is_same(decltype(v), decltype(w)));
|
||||
static_assert(v != w);
|
||||
}
|
||||
template void check<0>();
|
||||
template void check<10>(); // FIXME: expected-note 2{{instantiation of}}
|
||||
template void check<20>();
|
||||
template void check<30>(); // FIXME: expected-note 2{{instantiation of}}
|
||||
template void check<40>();
|
||||
template void check<50>();
|
||||
template void check<60>();
|
||||
template void check<70>();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user