diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -812,7 +812,7 @@ getArgKind(0) == DiagnosticsEngine::ak_std_string) { const std::string &S = getArgStdStr(0); for (char c : S) { - if (llvm::sys::locale::isPrint(c) || c == '\t') { + if (llvm::sys::locale::isPrint(c) || c == '\t' || c == '\n') { OutStr.push_back(c); } } diff --git a/clang/lib/Frontend/TextDiagnosticPrinter.cpp b/clang/lib/Frontend/TextDiagnosticPrinter.cpp --- a/clang/lib/Frontend/TextDiagnosticPrinter.cpp +++ b/clang/lib/Frontend/TextDiagnosticPrinter.cpp @@ -116,9 +116,24 @@ SmallString<100> OutStr; Info.FormatDiagnostic(OutStr); - llvm::raw_svector_ostream DiagMessageStream(OutStr); + // If the diagnostic message is formatted into multiple lines, split the + // first line and feed it into printDiagnosticOptions so that we print the + // options only on the first line instead of the last line. + SmallString<100> InitStr; + size_t NewlinePos = OutStr.find_first_of('\n'); + if (NewlinePos != StringRef::npos) { + for (size_t I = 0; I != NewlinePos; ++I) + InitStr.push_back(OutStr[I]); + } else + InitStr = OutStr; + + llvm::raw_svector_ostream DiagMessageStream(InitStr); printDiagnosticOptions(DiagMessageStream, Level, Info, *DiagOpts); + // Append the remaining diagnostic message if there were multiple lines. + if (NewlinePos != StringRef::npos) + DiagMessageStream << OutStr.slice(NewlinePos, OutStr.size()); + // Keeps track of the starting position of the location // information (e.g., "foo.c:10:4:") that precedes the error // message. We use this information to determine how long the diff --git a/clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp --- a/clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp @@ -90,13 +90,19 @@ E = Diags.end(); I != E; ++I) { const PathDiagnostic *PD = *I; + std::string OutStr; std::string WarningMsg = (DiagOpts.ShouldDisplayDiagnosticName ? " [" + PD->getCheckerName() + "]" : "") .str(); - reportPiece(WarnID, PD->getLocation().asLocation(), - (PD->getShortDescription() + WarningMsg).str(), + size_t NewlinePos = PD->getShortDescription().find_first_of('\n'); + if (NewlinePos != std::string::npos) + OutStr = PD->getShortDescription().str().insert(NewlinePos, WarningMsg); + else + OutStr = (PD->getShortDescription() + WarningMsg).str(); + + reportPiece(WarnID, PD->getLocation().asLocation(), OutStr, PD->path.back()->getRanges(), PD->path.back()->getFixits()); // First, add extra notes, even if paths should not be included. diff --git a/clang/test/Analysis/padding_message.cpp b/clang/test/Analysis/padding_message.cpp --- a/clang/test/Analysis/padding_message.cpp +++ b/clang/test/Analysis/padding_message.cpp @@ -1,11 +1,11 @@ // RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -std=c++14 -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s // expected-warning@+7{{\ -Excessive padding in 'struct IntSandwich' (6 padding bytes, where 2 is optimal). \ -Optimal fields order: \ -i, \ -c1, \ -c2, \ +Excessive padding in 'struct IntSandwich' (6 padding bytes, where 2 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +i, \n\ +c1, \n\ +c2, \n\ }} struct IntSandwich { char c1; @@ -14,11 +14,11 @@ }; // expected-warning@+7{{\ -Excessive padding in 'struct TurDuckHen' (6 padding bytes, where 2 is optimal). \ -Optimal fields order: \ -i, \ -c1, \ -c2, \ +Excessive padding in 'struct TurDuckHen' (6 padding bytes, where 2 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +i, \n\ +c1, \n\ +c2, \n\ }} struct TurDuckHen { char c1; @@ -29,15 +29,15 @@ #pragma pack(push) #pragma pack(2) // expected-warning@+11{{\ -Excessive padding in 'struct SmallIntSandwich' (4 padding bytes, where 0 is optimal). \ -Optimal fields order: \ -i1, \ -i2, \ -i3, \ -c1, \ -c2, \ -c3, \ -c4, \ +Excessive padding in 'struct SmallIntSandwich' (4 padding bytes, where 0 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +i1, \n\ +i2, \n\ +i3, \n\ +c1, \n\ +c2, \n\ +c3, \n\ +c4, \n\ }} struct SmallIntSandwich { char c1; @@ -57,11 +57,11 @@ }; // expected-warning@+7{{\ -Excessive padding in 'struct HoldsAUnion' (6 padding bytes, where 2 is optimal). \ -Optimal fields order: \ -u, \ -c1, \ -c2, \ +Excessive padding in 'struct HoldsAUnion' (6 padding bytes, where 2 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +u, \n\ +c1, \n\ +c2, \n\ }} struct HoldsAUnion { char c1; @@ -78,11 +78,11 @@ }; // expected-warning@+7{{\ -Excessive padding in 'struct StructSandwich' (6 padding bytes, where 2 is optimal). \ -Optimal fields order: \ -m, \ -s, \ -s2, \ +Excessive padding in 'struct StructSandwich' (6 padding bytes, where 2 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +m, \n\ +s, \n\ +s2, \n\ }} struct StructSandwich { struct SmallCharArray s; @@ -91,11 +91,11 @@ }; // expected-warning@+7{{\ -Excessive padding in 'TypedefSandwich' (6 padding bytes, where 2 is optimal). \ -Optimal fields order: \ -i, \ -c1, \ -c2, \ +Excessive padding in 'TypedefSandwich' (6 padding bytes, where 2 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +i, \n\ +c1, \n\ +c2, \n\ }} typedef struct { char c1; @@ -104,11 +104,11 @@ } TypedefSandwich; // expected-warning@+7{{\ -Excessive padding in 'struct StructAttrAlign' (10 padding bytes, where 2 is optimal). \ -Optimal fields order: \ -i, \ -c1, \ -c2, \ +Excessive padding in 'struct StructAttrAlign' (10 padding bytes, where 2 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +i, \n\ +c1, \n\ +c2, \n\ }} struct StructAttrAlign { char c1; @@ -117,12 +117,12 @@ } __attribute__((aligned(8))); // expected-warning@+8{{\ -Excessive padding in 'struct OverlyAlignedChar' (8185 padding bytes, where 4089 is optimal). \ -Optimal fields order: \ -c, \ -c1, \ -c2, \ -x, \ +Excessive padding in 'struct OverlyAlignedChar' (8185 padding bytes, where 4089 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +c, \n\ +c1, \n\ +c2, \n\ +x, \n\ }} struct OverlyAlignedChar { char c1; @@ -132,11 +132,11 @@ }; // expected-warning@+7{{\ -Excessive padding in 'struct HoldsOverlyAlignedChar' (8190 padding bytes, where 4094 is optimal). \ -Optimal fields order: \ -o, \ -c1, \ -c2, \ +Excessive padding in 'struct HoldsOverlyAlignedChar' (8190 padding bytes, where 4094 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +o, \n\ +c1, \n\ +c2, \n\ }} struct HoldsOverlyAlignedChar { char c1; @@ -146,11 +146,11 @@ void internalStructFunc() { // expected-warning@+7{{\ -Excessive padding in 'struct X' (6 padding bytes, where 2 is optimal). \ -Optimal fields order: \ -t, \ -c1, \ -c2, \ +Excessive padding in 'struct X' (6 padding bytes, where 2 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +t, \n\ +c1, \n\ +c2, \n\ }} struct X { char c1; @@ -162,11 +162,11 @@ void typedefStructFunc() { // expected-warning@+7{{\ -Excessive padding in 'S' (6 padding bytes, where 2 is optimal). \ -Optimal fields order: \ -t, \ -c1, \ -c2, \ +Excessive padding in 'S' (6 padding bytes, where 2 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +t, \n\ +c1, \n\ +c2, \n\ }} typedef struct { char c1; @@ -177,11 +177,11 @@ } // expected-warning@+7{{\ -Excessive padding in 'struct DefaultAttrAlign' (22 padding bytes, where 6 is optimal). \ -Optimal fields order: \ -i, \ -c1, \ -c2, \ +Excessive padding in 'struct DefaultAttrAlign' (22 padding bytes, where 6 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +i, \n\ +c1, \n\ +c2, \n\ }} struct DefaultAttrAlign { char c1; @@ -190,11 +190,11 @@ } __attribute__((aligned)); // expected-warning@+7{{\ -Excessive padding in 'struct SmallArrayShortSandwich' (2 padding bytes, where 0 is optimal). \ -Optimal fields order: \ -s, \ -c1, \ -c2, \ +Excessive padding in 'struct SmallArrayShortSandwich' (2 padding bytes, where 0 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +s, \n\ +c1, \n\ +c2, \n\ }} struct SmallArrayShortSandwich { char c1; @@ -203,11 +203,11 @@ } ShortArray[20]; // expected-warning@+7{{\ -Excessive padding in 'struct SmallArrayInFunc' (2 padding bytes, where 0 is optimal). \ -Optimal fields order: \ -s, \ -c1, \ -c2, \ +Excessive padding in 'struct SmallArrayInFunc' (2 padding bytes, where 0 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +s, \n\ +c1, \n\ +c2, \n\ }} struct SmallArrayInFunc { char c1; @@ -220,11 +220,11 @@ } // expected-warning@+7{{\ -Excessive padding in 'class VirtualIntSandwich' (10 padding bytes, where 2 is optimal). \ -Optimal fields order: \ -i, \ -c1, \ -c2, \ +Excessive padding in 'class VirtualIntSandwich' (10 padding bytes, where 2 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +i, \n\ +c1, \n\ +c2, \n\ }} class VirtualIntSandwich { virtual void foo() {} @@ -235,12 +235,12 @@ // constructed so as not to have tail padding // expected-warning@+8{{\ -Excessive padding in 'class InnerPaddedB' (6 padding bytes, where 2 is optimal). \ -Optimal fields order: \ -i1, \ -i2, \ -c1, \ -c2, \ +Excessive padding in 'class InnerPaddedB' (6 padding bytes, where 2 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +i1, \n\ +i2, \n\ +c1, \n\ +c2, \n\ }} class InnerPaddedB { char c1; @@ -252,11 +252,11 @@ class Empty {}; // no-warning // expected-warning@+7{{\ -Excessive padding in 'class LotsOfSpace' (6 padding bytes, where 2 is optimal). \ -Optimal fields order: \ -i, \ -e1, \ -e2, \ +Excessive padding in 'class LotsOfSpace' (6 padding bytes, where 2 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +i, \n\ +e1, \n\ +e2, \n\ }} class LotsOfSpace { Empty e1; @@ -265,20 +265,20 @@ }; // expected-warning@+7{{\ -Excessive padding in 'struct TypedefSandwich2' (6 padding bytes, where 2 is optimal). \ -Optimal fields order: \ -t, \ -c1, \ -c2, \ +Excessive padding in 'struct TypedefSandwich2' (6 padding bytes, where 2 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +t, \n\ +c1, \n\ +c2, \n\ }} typedef struct TypedefSandwich2 { char c1; // expected-warning@+7{{\ -Excessive padding in 'TypedefSandwich2::NestedTypedef' (6 padding bytes, where 2 is optimal). \ -Optimal fields order: \ -i, \ -c1, \ -c2, \ +Excessive padding in 'TypedefSandwich2::NestedTypedef' (6 padding bytes, where 2 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +i, \n\ +c1, \n\ +c2, \n\ }} typedef struct { char c1; @@ -292,11 +292,11 @@ template struct Foo { // expected-warning@+7{{\ -Excessive padding in 'struct Foo::Nested' (6 padding bytes, where 2 is optimal). \ -Optimal fields order: \ -t, \ -c1, \ -c2, \ +Excessive padding in 'struct Foo::Nested' (6 padding bytes, where 2 is optimal). [optin.performance.Padding]\n\ +Optimal fields order: \n\ +t, \n\ +c1, \n\ +c2, \n\ }} struct Nested { char c1;