diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2999,6 +2999,10 @@ def warn_objc_string_literal_comparison : Warning< "direct comparison of a string literal has undefined behavior">, InGroup; +def warn_concatenated_literal_array_init : Warning< + "concatenated literal in a string array initialization - " + "possibly missing a comma">, + InGroup>; def warn_concatenated_nsarray_literal : Warning< "concatenated NSString literal for an NSArray expression - " "possibly missing a comma">, diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6907,6 +6907,11 @@ << DIE->getSourceRange(); Diag(InitArgList[I]->getBeginLoc(), diag::note_designated_init_mixed) << InitArgList[I]->getSourceRange(); + } else if (StringLiteral *SL = dyn_cast(InitArgList[I])) { + unsigned numConcat = SL->getNumConcatenated(); + // Diagnose missing comma in string array initialization. + if (numConcat > 1) + Diag(SL->getBeginLoc(), diag::warn_concatenated_literal_array_init); } } diff --git a/clang/test/Sema/string-concat.c b/clang/test/Sema/string-concat.c new file mode 100644 --- /dev/null +++ b/clang/test/Sema/string-concat.c @@ -0,0 +1,41 @@ + +// RUN: %clang_cc1 -x c -fsyntax-only -verify %s +// RUN: %clang_cc1 -x c++ -fsyntax-only -verify %s + +const char *test1[] = { + "basic_filebuf", + "basic_ios", + "future", + "optional", + "packaged_task" // expected-warning{{concatenated literal in a string array initialization - possibly missing a comma}} + "promise", + "shared_future", + "shared_lock", + "shared_ptr", + "thread", + "unique_ptr", + "unique_lock", + "weak_ptr", +}; + +const char *test2[] = {"basic_filebuf", + "basic_ios" // expected-warning{{concatenated literal in a string array initialization - possibly missing a comma}} + "future" + "optional", + "packaged_task"}; + +const char *test3[] = {"basic_filebuf", "basic_ios", + "future" "optional", // expected-warning{{concatenated literal in a string array initialization - possibly missing a comma}} + "packaged_task", "promise"}; + +const char *test4[] = {"basic_filebuf", "basic_ios" // expected-warning{{concatenated literal in a string array initialization - possibly missing a comma}} + "future", "optional", + "packaged_task", "promise"}; + +#define BASIC_IOS "basic_ios" +#define FUTURE "future" +const char *test5[] = {"basic_filebuf", BASIC_IOS // expected-warning{{concatenated literal in a string array initialization - possibly missing a comma}} + FUTURE, "optional", + "packaged_task", "promise"}; + +const char *test6[] = {"basic_filebuf", "future" "optional", "packaged_task"}; // expected-warning{{concatenated literal in a string array initialization - possibly missing a comma}}