bruno created this revision. bruno added reviewers: manmanren, doug.gregor. bruno added a subscriber: cfe-commits.
Calls to TransformExpr for NSDictionary elements (keys and values) in TransformObjCDictionaryLiteral might fail to obtain TypoCorrections. This is OK, but the early exits with ExprError() don't allow TransformExpr to run for other elements. This avoids typo correction suggestions to kick in and has a major drawback to compile time; it forces Transform to call TryTransform more times than it should. Before this patch, the testcase added used to take 5s to compile!!! A bit more elaborate NSDictionary literal with some undeclared enums would make the compiler take 22min to run, followed by a crash. http://reviews.llvm.org/D22183 Files: lib/Sema/TreeTransform.h test/SemaObjC/objc-dictionary-literal.m Index: test/SemaObjC/objc-dictionary-literal.m =================================================================== --- test/SemaObjC/objc-dictionary-literal.m +++ test/SemaObjC/objc-dictionary-literal.m @@ -63,3 +63,11 @@ return 0; } +enum XXXYYYZZZType { XXXYYYZZZTypeAny }; // expected-note {{'XXXYYYZZZTypeAny' declared here}} + +void foo() { + NSDictionary *d = @{ + @"A" : @(XXXYYYZZZTypeA), // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeA'; did you mean 'XXXYYYZZZTypeAny'}} + @"F" : @(XXXYYYZZZTypeSomethingSomething), // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeSomethingSomething'}} + }; +} Index: lib/Sema/TreeTransform.h =================================================================== --- lib/Sema/TreeTransform.h +++ lib/Sema/TreeTransform.h @@ -10956,23 +10956,19 @@ // Transform and check key. ExprResult Key = getDerived().TransformExpr(OrigElement.Key); - if (Key.isInvalid()) - return ExprError(); - - if (Key.get() != OrigElement.Key) + if (!Key.isInvalid() && Key.get() != OrigElement.Key) ArgChanged = true; // Transform and check value. ExprResult Value = getDerived().TransformExpr(OrigElement.Value); - if (Value.isInvalid()) - return ExprError(); - - if (Value.get() != OrigElement.Value) + if (!Value.isInvalid() && Value.get() != OrigElement.Value) ArgChanged = true; ObjCDictionaryElement Element = { - Key.get(), Value.get(), SourceLocation(), None + Key.isInvalid() ? OrigElement.Key : Key.get(), + Value.isInvalid() ? OrigElement.Value : Value.get(), SourceLocation(), + None }; Elements.push_back(Element); }
Index: test/SemaObjC/objc-dictionary-literal.m =================================================================== --- test/SemaObjC/objc-dictionary-literal.m +++ test/SemaObjC/objc-dictionary-literal.m @@ -63,3 +63,11 @@ return 0; } +enum XXXYYYZZZType { XXXYYYZZZTypeAny }; // expected-note {{'XXXYYYZZZTypeAny' declared here}} + +void foo() { + NSDictionary *d = @{ + @"A" : @(XXXYYYZZZTypeA), // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeA'; did you mean 'XXXYYYZZZTypeAny'}} + @"F" : @(XXXYYYZZZTypeSomethingSomething), // expected-error {{use of undeclared identifier 'XXXYYYZZZTypeSomethingSomething'}} + }; +} Index: lib/Sema/TreeTransform.h =================================================================== --- lib/Sema/TreeTransform.h +++ lib/Sema/TreeTransform.h @@ -10956,23 +10956,19 @@ // Transform and check key. ExprResult Key = getDerived().TransformExpr(OrigElement.Key); - if (Key.isInvalid()) - return ExprError(); - - if (Key.get() != OrigElement.Key) + if (!Key.isInvalid() && Key.get() != OrigElement.Key) ArgChanged = true; // Transform and check value. ExprResult Value = getDerived().TransformExpr(OrigElement.Value); - if (Value.isInvalid()) - return ExprError(); - - if (Value.get() != OrigElement.Value) + if (!Value.isInvalid() && Value.get() != OrigElement.Value) ArgChanged = true; ObjCDictionaryElement Element = { - Key.get(), Value.get(), SourceLocation(), None + Key.isInvalid() ? OrigElement.Key : Key.get(), + Value.isInvalid() ? OrigElement.Value : Value.get(), SourceLocation(), + None }; Elements.push_back(Element); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits