summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaelyn Takata <rikka@google.com>2014-11-21 18:48:00 +0000
committerKaelyn Takata <rikka@google.com>2014-11-21 18:48:00 +0000
commit4c3ffc4fef388ff9b2b9b92b25bbd4960f337dfa (patch)
tree0e64b5c6b9ebc17a40979b31193816844b553baa
parent5ca2ecd2b200360ae33e047e3da418c8852564c2 (diff)
downloadbcm5719-llvm-4c3ffc4fef388ff9b2b9b92b25bbd4960f337dfa.tar.gz
bcm5719-llvm-4c3ffc4fef388ff9b2b9b92b25bbd4960f337dfa.zip
Properly correct initializer expressions based on whether they would be valid.
llvm-svn: 222550
-rw-r--r--clang/lib/Sema/SemaDecl.cpp17
-rw-r--r--clang/test/SemaCXX/typo-correction-delayed.cpp34
2 files changed, 51 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d44f1417762..08f5c3c8b8a 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -8799,6 +8799,23 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
Args = MultiExprArg(CXXDirectInit->getExprs(),
CXXDirectInit->getNumExprs());
+ // Try to correct any TypoExprs if there might be some in the initialization
+ // arguments (TypoExprs are marked as type-dependent).
+ // TODO: Handle typo correction when there's more than one argument?
+ if (Args.size() == 1 && Expr::hasAnyTypeDependentArguments(Args)) {
+ ExprResult Res =
+ CorrectDelayedTyposInExpr(Args[0], [this, Entity, Kind](Expr *E) {
+ InitializationSequence Init(*this, Entity, Kind, MultiExprArg(E));
+ return Init.Failed() ? ExprError() : E;
+ });
+ if (Res.isInvalid()) {
+ VDecl->setInvalidDecl();
+ return;
+ }
+ if (Res.get() != Args[0])
+ Args[0] = Res.get();
+ }
+
InitializationSequence InitSeq(*this, Entity, Kind, Args);
ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT);
if (Result.isInvalid()) {
diff --git a/clang/test/SemaCXX/typo-correction-delayed.cpp b/clang/test/SemaCXX/typo-correction-delayed.cpp
index c82f865a863..124f0ec2a1c 100644
--- a/clang/test/SemaCXX/typo-correction-delayed.cpp
+++ b/clang/test/SemaCXX/typo-correction-delayed.cpp
@@ -59,3 +59,37 @@ void testExprFilter(Item *i) {
Item *j;
j = i->Next(); // expected-error {{no member named 'Next' in 'Item'; did you mean 'next'?}}
}
+
+// Test that initializer expressions are handled correctly and that the type
+// being initialized is taken into account when choosing a correction.
+namespace initializerCorrections {
+struct Node {
+ string text() const;
+ // Node* Next() is not implemented yet
+};
+void f(Node *node) {
+ // text is only an edit distance of 1 from Next, but would trigger type
+ // conversion errors if used in this initialization expression.
+ Node *next = node->Next(); // expected-error-re {{no member named 'Next' in 'initializerCorrections::Node'{{$}}}}
+}
+
+struct LinkedNode {
+ LinkedNode* next(); // expected-note {{'next' declared here}}
+ string text() const;
+};
+void f(LinkedNode *node) {
+ // text and next are equidistant from Next, but only one results in a valid
+ // initialization expression.
+ LinkedNode *next = node->Next(); // expected-error {{no member named 'Next' in 'initializerCorrections::LinkedNode'; did you mean 'next'?}}
+}
+
+struct NestedNode {
+ NestedNode* Nest();
+ NestedNode* next();
+ string text() const;
+};
+void f(NestedNode *node) {
+ // There are two equidistant, usable corrections for Next: next and Nest
+ NestedNode *next = node->Next(); // expected-error-re {{no member named 'Next' in 'initializerCorrections::NestedNode'{{$}}}}
+}
+}
OpenPOWER on IntegriCloud