aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Sema/Sema.h3
-rw-r--r--lib/Sema/SemaOverload.cpp32
-rw-r--r--lib/Sema/SemaStmt.cpp2
-rw-r--r--test/SemaCXX/typo-correction.cpp8
4 files changed, 38 insertions, 7 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 77ae346e67..12096f5fcb 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1583,7 +1583,8 @@ public:
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
SourceLocation RParenLoc,
- Expr *ExecConfig);
+ Expr *ExecConfig,
+ bool AllowTypoCorrection=true);
ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc,
unsigned Opc,
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 3333b4eea9..36b6946a03 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -9215,6 +9215,21 @@ class RecoveryCallCCC : public CorrectionCandidateCallback {
unsigned NumArgs;
bool HasExplicitTemplateArgs;
};
+
+// Callback that effectively disabled typo correction
+class NoTypoCorrectionCCC : public CorrectionCandidateCallback {
+ public:
+ NoTypoCorrectionCCC() {
+ WantTypeSpecifiers = false;
+ WantExpressionKeywords = false;
+ WantCXXNamedCasts = false;
+ WantRemainingKeywords = false;
+ }
+
+ virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+ return false;
+ }
+};
}
/// Attempts to recover from a call where no functions were found.
@@ -9226,7 +9241,7 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
SourceLocation RParenLoc,
- bool EmptyLookup) {
+ bool EmptyLookup, bool AllowTypoCorrection) {
CXXScopeSpec SS;
SS.Adopt(ULE->getQualifierLoc());
@@ -9241,10 +9256,14 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
Sema::LookupOrdinaryName);
RecoveryCallCCC Validator(SemaRef, NumArgs, ExplicitTemplateArgs != 0);
+ NoTypoCorrectionCCC RejectAll;
+ CorrectionCandidateCallback *CCC = AllowTypoCorrection ?
+ (CorrectionCandidateCallback*)&Validator :
+ (CorrectionCandidateCallback*)&RejectAll;
if (!DiagnoseTwoPhaseLookup(SemaRef, Fn->getExprLoc(), SS, R,
ExplicitTemplateArgs, Args, NumArgs) &&
(!EmptyLookup ||
- SemaRef.DiagnoseEmptyLookup(S, SS, R, Validator,
+ SemaRef.DiagnoseEmptyLookup(S, SS, R, *CCC,
ExplicitTemplateArgs, Args, NumArgs)))
return ExprError();
@@ -9283,7 +9302,8 @@ Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
SourceLocation RParenLoc,
- Expr *ExecConfig) {
+ Expr *ExecConfig,
+ bool AllowTypoCorrection) {
#ifndef NDEBUG
if (ULE->requiresADL()) {
// To do ADL, we must have found an unqualified name.
@@ -9331,7 +9351,8 @@ Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
return Owned(CE);
}
return BuildRecoveryCallExpr(*this, S, Fn, ULE, LParenLoc, Args, NumArgs,
- RParenLoc, /*EmptyLookup=*/true);
+ RParenLoc, /*EmptyLookup=*/true,
+ AllowTypoCorrection);
}
UnbridgedCasts.restore();
@@ -9353,7 +9374,8 @@ Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
// have meant to call.
ExprResult Recovery = BuildRecoveryCallExpr(*this, S, Fn, ULE, LParenLoc,
Args, NumArgs, RParenLoc,
- /*EmptyLookup=*/false);
+ /*EmptyLookup=*/false,
+ AllowTypoCorrection);
if (!Recovery.isInvalid())
return Recovery;
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 86bb74040a..0eb8d2863c 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -1286,7 +1286,7 @@ static ExprResult BuildForRangeBeginEndCall(Sema &SemaRef, Scope *S,
FoundNames.begin(), FoundNames.end(),
/*LookInStdNamespace=*/true);
CallExpr = SemaRef.BuildOverloadedCallExpr(S, Fn, Fn, Loc, &Range, 1, Loc,
- 0);
+ 0, /*AllowTypoCorrection=*/false);
if (CallExpr.isInvalid()) {
SemaRef.Diag(Range->getLocStart(), diag::note_for_range_type)
<< Range->getType();
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index 6a3a2976a5..556e654a2d 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -149,3 +149,11 @@ void Test3() {
Provoke("foo", true); // expected-error{{use of undeclared identifier 'Provoke'; did you mean 'provoke'?}}
Provoke("foo", 7, 22); // expected-error{{use of undeclared identifier 'Provoke'}}
}
+
+// PR 11737 - Don't try to typo-correct the implicit 'begin' and 'end' in a
+// C++11 for-range statement.
+struct R {};
+bool begun(R);
+void RangeTest() {
+ for (auto b : R()) {} // expected-error {{use of undeclared identifier 'begin'}} expected-note {{range has type}}
+}