diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 62 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 29 |
2 files changed, 81 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 33c8a83b40f..3eda4209402 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -12,8 +12,10 @@ //===----------------------------------------------------------------------===// #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/DelayedDiagnostic.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" +#include "clang/Sema/ScopeInfo.h" #include "clang/Sema/AnalysisBasedWarnings.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTMutationListener.h" @@ -9360,6 +9362,39 @@ bool Sema::VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result, return false; } +void Sema::ExpressionEvaluationContextRecord::Destroy() { + delete PotentiallyReferenced; + delete SavedDiag; + delete SavedRuntimeDiag; + delete SavedDelayedDiag; + PotentiallyReferenced = 0; + SavedDiag = 0; + SavedRuntimeDiag = 0; + SavedDelayedDiag = 0; +} + +void Sema::ExpressionEvaluationContextRecord::addDiagnostic( + SourceLocation Loc, const PartialDiagnostic &PD) { + if (!SavedDiag) + SavedDiag = new PotentiallyEmittedDiagnostics; + SavedDiag->push_back(std::make_pair(Loc, PD)); +} + +void Sema::ExpressionEvaluationContextRecord::addRuntimeDiagnostic( + const sema::PossiblyUnreachableDiag &PUD) { + if (!SavedRuntimeDiag) + SavedRuntimeDiag = new PotentiallyEmittedPossiblyUnreachableDiag; + SavedRuntimeDiag->push_back(PUD); +} + +void Sema::ExpressionEvaluationContextRecord::addDelayedDiagnostic( + const sema::DelayedDiagnostic &DD) { + if (!SavedDelayedDiag) + SavedDelayedDiag = new PotentiallyEmittedDelayedDiag; + SavedDelayedDiag->push_back(DD); +} + + void Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext) { ExprEvalContexts.push_back( @@ -9386,14 +9421,32 @@ void Sema::PopExpressionEvaluationContext() { MarkDeclarationReferenced(I->first, I->second); } - if (Rec.PotentiallyDiagnosed) { + if (Rec.SavedDiag) { // Emit any pending diagnostics. for (PotentiallyEmittedDiagnostics::iterator - I = Rec.PotentiallyDiagnosed->begin(), - IEnd = Rec.PotentiallyDiagnosed->end(); + I = Rec.SavedDiag->begin(), + IEnd = Rec.SavedDiag->end(); I != IEnd; ++I) Diag(I->first, I->second); } + + if (Rec.SavedDelayedDiag) { + // Emit any pending delayed diagnostics. + for (PotentiallyEmittedDelayedDiag::iterator + I = Rec.SavedDelayedDiag->begin(), + IEnd = Rec.SavedDelayedDiag->end(); + I != IEnd; ++I) + DelayedDiagnostics.add(*I); + } + + if (Rec.SavedRuntimeDiag) { + // Emit any pending runtime diagnostics. + for (PotentiallyEmittedPossiblyUnreachableDiag::iterator + I = Rec.SavedRuntimeDiag->begin(), + IEnd = Rec.SavedRuntimeDiag->end(); + I != IEnd; ++I) + FunctionScopes.back()->PossiblyUnreachableDiags.push_back(*I); + } } // When are coming out of an unevaluated context, clear out any @@ -9759,7 +9812,8 @@ bool Sema::DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, return true; case PotentiallyPotentiallyEvaluated: - ExprEvalContexts.back().addDiagnostic(Loc, PD); + ExprEvalContexts.back().addRuntimeDiagnostic( + sema::PossiblyUnreachableDiag(PD, Loc, Statement)); break; } diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 0d307492667..f3582975ecd 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1057,23 +1057,40 @@ static QualType inferARCLifetimeForPointee(Sema &S, QualType type, } else if (type->isObjCARCImplicitlyUnretainedType()) { implicitLifetime = Qualifiers::OCL_ExplicitNone; - // If we are in an unevaluated context, like sizeof, assume ExplicitNone and + // If we are in an unevaluated context, like sizeof, assume Autoreleasing and // don't give error. } else if (S.ExprEvalContexts.back().Context == Sema::Unevaluated || S.ExprEvalContexts.back().Context == Sema::ConstantEvaluated) { - implicitLifetime = Qualifiers::OCL_ExplicitNone; + implicitLifetime = Qualifiers::OCL_Autoreleasing; // If that failed, give an error and recover using __autoreleasing. } else { // These types can show up in private ivars in system headers, so // we need this to not be an error in those cases. Instead we // want to delay. + // + // Also, make sure we delay appropriately in + // PotentiallyPotentiallyEvaluated contexts. if (S.DelayedDiagnostics.shouldDelayDiagnostics()) { - S.DelayedDiagnostics.add( - sema::DelayedDiagnostic::makeForbiddenType(loc, - diag::err_arc_indirect_no_ownership, type, isReference)); + if (S.ExprEvalContexts.back().Context == + Sema::PotentiallyPotentiallyEvaluated) { + S.ExprEvalContexts.back().addDelayedDiagnostic( + sema::DelayedDiagnostic::makeForbiddenType(loc, + diag::err_arc_indirect_no_ownership, type, isReference)); + } else { + S.DelayedDiagnostics.add( + sema::DelayedDiagnostic::makeForbiddenType(loc, + diag::err_arc_indirect_no_ownership, type, isReference)); + } } else { - S.Diag(loc, diag::err_arc_indirect_no_ownership) << type << isReference; + if (S.ExprEvalContexts.back().Context == + Sema::PotentiallyPotentiallyEvaluated) { + S.ExprEvalContexts.back().addDiagnostic(loc, + S.PDiag(diag::err_arc_indirect_no_ownership) + << type << isReference); + } else { + S.Diag(loc, diag::err_arc_indirect_no_ownership) << type << isReference; + } } implicitLifetime = Qualifiers::OCL_Autoreleasing; } |