Index: include/clang/Basic/DiagnosticLexKinds.td =================================================================== --- include/clang/Basic/DiagnosticLexKinds.td +++ include/clang/Basic/DiagnosticLexKinds.td @@ -403,7 +403,9 @@ def err_pp_invalid_directive : Error<"invalid preprocessing directive">; def err_pp_directive_required : Error< "%0 must be used within a preprocessing directive">; -def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal; +def err_pp_file_not_found : Error< + "'%0' file not found%select{|, possibly due to leading or trailing " + "non-alphanumeric characters in the file name}1">, DefaultFatal; def err_pp_through_header_not_found : Error< "'%0' required for precompiled header not found">, DefaultFatal; def err_pp_through_header_not_seen : Error< Index: lib/Lex/PPDirectives.cpp =================================================================== --- lib/Lex/PPDirectives.cpp +++ lib/Lex/PPDirectives.cpp @@ -1859,6 +1859,7 @@ // If the file could not be located and it was included via angle // brackets, we can attempt a lookup as though it were a quoted path to // provide the user with a possible fixit. + bool isFileNotFoundLikelyTypo = false; if (isAngled) { File = LookupFile( FilenameLoc, @@ -1868,16 +1869,27 @@ Callbacks ? &RelativePath : nullptr, &SuggestedModule, &IsMapped); if (File) { SourceRange Range(FilenameTok.getLocation(), CharEnd); - Diag(FilenameTok, diag::err_pp_file_not_found_not_fatal) << - Filename << - FixItHint::CreateReplacement(Range, "\"" + Filename.str() + "\""); + Diag(FilenameTok, diag::err_pp_file_not_found_not_fatal) + << Filename + << FixItHint::CreateReplacement(Range, + "\"" + Filename.str() + "\"") + << isFileNotFoundLikelyTypo; } } // If the file is still not found, just go with the vanilla diagnostic - if (!File) - Diag(FilenameTok, diag::err_pp_file_not_found) << Filename - << FilenameRange; + if (!File) { + // Assuming filename logically starts and end with alphnumeric + // character + if (!isAlphanumeric(Filename.front()) || + !isAlphanumeric(Filename.back())) { + isFileNotFoundLikelyTypo = true; + Diag(FilenameTok, diag::err_pp_file_not_found) + << Filename << isFileNotFoundLikelyTypo; + } + Diag(FilenameTok, diag::err_pp_file_not_found) + << Filename << FilenameRange << isFileNotFoundLikelyTypo; + } } } Index: lib/Lex/Pragma.cpp =================================================================== --- lib/Lex/Pragma.cpp +++ lib/Lex/Pragma.cpp @@ -514,7 +514,7 @@ nullptr, CurDir, nullptr, nullptr, nullptr, nullptr); if (!File) { if (!SuppressIncludeNotFoundError) - Diag(FilenameTok, diag::err_pp_file_not_found) << Filename; + Diag(FilenameTok, diag::err_pp_file_not_found) << Filename << 0; return; } Index: test/Preprocessor/include-likely-typo.c =================================================================== --- /dev/null +++ test/Preprocessor/include-likely-typo.c @@ -0,0 +1,2 @@ +// RUN: not %clang_cc1 -verify -frewrite-includes +#include "" @expected-error {{'' file not found, possibly due to leading or trailing non-alphanumeric characters in the file name}}