Author: Dávid Bolvanský Date: 2020-08-12T02:18:01+02:00 New Revision: b9af72bffe5f2769f3a7858a785981f89137a0ce
URL: https://github.com/llvm/llvm-project/commit/b9af72bffe5f2769f3a7858a785981f89137a0ce DIFF: https://github.com/llvm/llvm-project/commit/b9af72bffe5f2769f3a7858a785981f89137a0ce.diff LOG: [Diagnostics] Reworked -Wstring-concatenation Added: Modified: clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaExpr.cpp clang/test/Sema/string-concat.c Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 77e15f187e53..fee748bf9f9d 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12886,6 +12886,53 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { AttributeCommonInfo::AS_Pragma)); } + if (var->hasInit() && isa<InitListExpr>(var->getInit())) { + const auto *ILE = cast<InitListExpr>(var->getInit()); + unsigned NumInits = ILE->getNumInits(); + if (NumInits > 2) + for (unsigned I = 0; I < NumInits; ++I) { + const auto *Init = ILE->getInit(I); + if (!Init) + break; + const auto *SL = dyn_cast<StringLiteral>(Init->IgnoreImpCasts()); + if (!SL) + break; + + unsigned NumConcat = SL->getNumConcatenated(); + // Diagnose missing comma in string array initialization. + // Do not warn when all the elements in the initializer are concatenated + // together. Do not warn for macros too. + if (NumConcat == 2 && !SL->getBeginLoc().isMacroID()) { + bool OnlyOneMissingComma = true; + for (unsigned J = I + 1; J < NumInits; ++J) { + const auto *Init = ILE->getInit(J); + if (!Init) + break; + const auto *SLJ = dyn_cast<StringLiteral>(Init->IgnoreImpCasts()); + if (!SLJ || SLJ->getNumConcatenated() > 1) { + OnlyOneMissingComma = false; + break; + } + } + + if (OnlyOneMissingComma) { + SmallVector<FixItHint, 1> Hints; + for (unsigned i = 0; i < NumConcat - 1; ++i) + Hints.push_back(FixItHint::CreateInsertion( + PP.getLocForEndOfToken(SL->getStrTokenLoc(i)), ",")); + + Diag(SL->getStrTokenLoc(1), + diag::warn_concatenated_literal_array_init) + << Hints; + Diag(SL->getBeginLoc(), + diag::note_concatenated_string_literal_silence); + } + // Warn just once. + break; + } + } + } + // All the following checks are C++ only. if (!getLangOpts().CPlusPlus) { // If this variable must be emitted, add it as an initializer for the diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index bea693f999ab..5e9fca13f1d0 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6870,7 +6870,6 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList, bool DiagnosedArrayDesignator = false; bool DiagnosedNestedDesignator = false; bool DiagnosedMixedDesignator = false; - bool DiagnosedMissingComma = false; // Check that any designated initializers are syntactically valid in the // current language mode. @@ -6912,37 +6911,6 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList, << DIE->getSourceRange(); Diag(InitArgList[I]->getBeginLoc(), diag::note_designated_init_mixed) << InitArgList[I]->getSourceRange(); - } else if (const auto *SL = dyn_cast<StringLiteral>(InitArgList[I])) { - unsigned NumConcat = SL->getNumConcatenated(); - // Diagnose missing comma in string array initialization. - // Do not warn when all the elements in the initializer are concatenated - // together. Do not warn for macros too. - if (!DiagnosedMissingComma && NumConcat == 2 && E > 2 && !SL->getBeginLoc().isMacroID()) { - bool OnlyOneMissingComma = true; - for (unsigned J = 0; J < E; ++J) { - if (J == I) - continue; - const auto *SLJ = dyn_cast<StringLiteral>(InitArgList[J]); - if (!SLJ || SLJ->getNumConcatenated() > 1) { - OnlyOneMissingComma = false; - break; - } - } - - if (OnlyOneMissingComma) { - SmallVector<FixItHint, 1> Hints; - for (unsigned i = 0; i < NumConcat - 1; ++i) - Hints.push_back(FixItHint::CreateInsertion( - PP.getLocForEndOfToken(SL->getStrTokenLoc(i)), ",")); - - Diag(SL->getStrTokenLoc(1), - diag::warn_concatenated_literal_array_init) - << Hints; - Diag(SL->getBeginLoc(), - diag::note_concatenated_string_literal_silence); - DiagnosedMissingComma = true; - } - } } } diff --git a/clang/test/Sema/string-concat.c b/clang/test/Sema/string-concat.c index 3dcde8844dff..b6bae9c95b0b 100644 --- a/clang/test/Sema/string-concat.c +++ b/clang/test/Sema/string-concat.c @@ -130,6 +130,25 @@ const char *not_warn4[] = {"title", "url" }; +typedef struct { + const char *a; + const char *b; + const char *c; +} A; + +const A not_warn5 = (A){"", + "" + "", + ""}; + +#ifdef __cplusplus +const A not_warn6 = A{"", + "" + "", + ""}; +#endif + + // Do not warn when all the elements in the initializer are concatenated together. const char *all_elems_in_init_concatenated[] = {"a" "b" "c"}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits