aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/Sema.h18
-rw-r--r--lib/Sema/SemaExpr.cpp43
2 files changed, 47 insertions, 14 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index baf9c23da5..ada8aa157a 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -339,6 +339,10 @@ public:
typedef std::vector<std::pair<SourceLocation, Decl *> >
PotentiallyReferencedDecls;
+ /// \brief A set of diagnostics that may be emitted.
+ typedef std::vector<std::pair<SourceLocation, PartialDiagnostic> >
+ PotentiallyEmittedDiagnostics;
+
/// \brief Data structure used to record current or nested
/// expression evaluation contexts.
struct ExpressionEvaluationContextRecord {
@@ -358,10 +362,14 @@ public:
/// evaluated.
PotentiallyReferencedDecls *PotentiallyReferenced;
+ /// \brief The set of diagnostics to emit should this potentially
+ /// potentially-evaluated context become evaluated.
+ PotentiallyEmittedDiagnostics *PotentiallyDiagnosed;
+
ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
unsigned NumTemporaries)
: Context(Context), NumTemporaries(NumTemporaries),
- PotentiallyReferenced(0) { }
+ PotentiallyReferenced(0), PotentiallyDiagnosed(0) { }
void addReferencedDecl(SourceLocation Loc, Decl *Decl) {
if (!PotentiallyReferenced)
@@ -369,9 +377,17 @@ public:
PotentiallyReferenced->push_back(std::make_pair(Loc, Decl));
}
+ void addDiagnostic(SourceLocation Loc, const PartialDiagnostic &PD) {
+ if (!PotentiallyDiagnosed)
+ PotentiallyDiagnosed = new PotentiallyEmittedDiagnostics;
+ PotentiallyDiagnosed->push_back(std::make_pair(Loc, PD));
+ }
+
void Destroy() {
delete PotentiallyReferenced;
+ delete PotentiallyDiagnosed;
PotentiallyReferenced = 0;
+ PotentiallyDiagnosed = 0;
}
};
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 1ca47a40aa..7cdc275c7e 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -271,7 +271,9 @@ bool Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) {
return true;
case PotentiallyPotentiallyEvaluated:
- // FIXME: queue it!
+ ExprEvalContexts.back().addDiagnostic(Expr->getLocStart(),
+ PDiag(diag::err_cannot_pass_objc_interface_to_vararg)
+ << Expr->getType() << CT);
break;
}
}
@@ -288,7 +290,9 @@ bool Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) {
break;
case PotentiallyPotentiallyEvaluated:
- // FIXME: queue it!
+ ExprEvalContexts.back().addDiagnostic(Expr->getLocStart(),
+ PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg)
+ << Expr->getType() << CT);
break;
}
}
@@ -6488,7 +6492,10 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
break;
case PotentiallyPotentiallyEvaluated:
- // FIXME: Queue it!
+ ExprEvalContexts.back().addDiagnostic(BuiltinLoc,
+ PDiag(diag::warn_offsetof_non_pod_type)
+ << SourceRange(CompPtr[0].LocStart, OC.LocEnd)
+ << Res->getType());
DidWarnAboutNonPOD = true;
break;
}
@@ -6957,16 +6964,26 @@ Sema::PopExpressionEvaluationContext() {
ExpressionEvaluationContextRecord Rec = ExprEvalContexts.back();
ExprEvalContexts.pop_back();
- if (Rec.Context == PotentiallyPotentiallyEvaluated &&
- Rec.PotentiallyReferenced) {
- // Mark any remaining declarations in the current position of the stack
- // as "referenced". If they were not meant to be referenced, semantic
- // analysis would have eliminated them (e.g., in ActOnCXXTypeId).
- for (PotentiallyReferencedDecls::iterator
- I = Rec.PotentiallyReferenced->begin(),
- IEnd = Rec.PotentiallyReferenced->end();
- I != IEnd; ++I)
- MarkDeclarationReferenced(I->first, I->second);
+ if (Rec.Context == PotentiallyPotentiallyEvaluated) {
+ if (Rec.PotentiallyReferenced) {
+ // Mark any remaining declarations in the current position of the stack
+ // as "referenced". If they were not meant to be referenced, semantic
+ // analysis would have eliminated them (e.g., in ActOnCXXTypeId).
+ for (PotentiallyReferencedDecls::iterator
+ I = Rec.PotentiallyReferenced->begin(),
+ IEnd = Rec.PotentiallyReferenced->end();
+ I != IEnd; ++I)
+ MarkDeclarationReferenced(I->first, I->second);
+ }
+
+ if (Rec.PotentiallyDiagnosed) {
+ // Emit any pending diagnostics.
+ for (PotentiallyEmittedDiagnostics::iterator
+ I = Rec.PotentiallyDiagnosed->begin(),
+ IEnd = Rec.PotentiallyDiagnosed->end();
+ I != IEnd; ++I)
+ Diag(I->first, I->second);
+ }
}
// When are coming out of an unevaluated context, clear out any