From: Richard Smith Date: Mon, 5 Jun 2017 22:29:36 +0000 (+0000) Subject: Fix crash when an 'import a module' TypoCorrection has its CorrectionDecls X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=532a634d671d1dad27d4e7ce0c97d9411ab22447;p=clang Fix crash when an 'import a module' TypoCorrection has its CorrectionDecls replaced by visible decls. Make sure that all paths through checkCorrectionVisibility set the RequiresImport flag appropriately, so we don't end up using a stale value. Patch by Jorge Gorbe! Differential Revision: https://reviews.llvm.org/D30963 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@304745 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 1d32e57968..1fb25f4e0e 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -3747,20 +3747,19 @@ static void LookupPotentialTypoResult(Sema &SemaRef, bool FindHidden); /// \brief Check whether the declarations found for a typo correction are -/// visible, and if none of them are, convert the correction to an 'import -/// a module' correction. +/// visible. Set the correction's RequiresImport flag to true if none of the +/// declarations are visible, false otherwise. static void checkCorrectionVisibility(Sema &SemaRef, TypoCorrection &TC) { - if (TC.begin() == TC.end()) - return; - TypoCorrection::decl_iterator DI = TC.begin(), DE = TC.end(); for (/**/; DI != DE; ++DI) if (!LookupResult::isVisible(SemaRef, *DI)) break; - // Nothing to do if all decls are visible. - if (DI == DE) + // No filtering needed if all decls are visible. + if (DI == DE) { + TC.setRequiresImport(false); return; + } llvm::SmallVector NewDecls(TC.begin(), DI); bool AnyVisibleDecls = !NewDecls.empty(); diff --git a/test/Modules/Inputs/crash-typo-correction-visibility/module.h b/test/Modules/Inputs/crash-typo-correction-visibility/module.h new file mode 100644 index 0000000000..6e73c3c729 --- /dev/null +++ b/test/Modules/Inputs/crash-typo-correction-visibility/module.h @@ -0,0 +1 @@ +struct member; diff --git a/test/Modules/Inputs/crash-typo-correction-visibility/module.modulemap b/test/Modules/Inputs/crash-typo-correction-visibility/module.modulemap new file mode 100644 index 0000000000..7310d6a2ef --- /dev/null +++ b/test/Modules/Inputs/crash-typo-correction-visibility/module.modulemap @@ -0,0 +1,3 @@ +module "module" { + header "module.h" +} diff --git a/test/Modules/crash-typo-correction-visibility.cpp b/test/Modules/crash-typo-correction-visibility.cpp new file mode 100644 index 0000000000..518293026a --- /dev/null +++ b/test/Modules/crash-typo-correction-visibility.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=module -o %T/module.pcm -emit-module %S/Inputs/crash-typo-correction-visibility/module.modulemap +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-file=%T/module.pcm %s -verify + +struct S { + int member; // expected-note {{declared here}} +}; + +int f(...); + +int b = sizeof(f(member)); // expected-error {{undeclared identifier 'member'}}