r297261 - [clang-format] Enable comment reflowing in multiline comments containing pragmas
Author: krasimir Date: Wed Mar 8 02:55:12 2017 New Revision: 297261 URL: http://llvm.org/viewvc/llvm-project?rev=297261&view=rev Log: [clang-format] Enable comment reflowing in multiline comments containing pragmas Summary: This patch enables comment reflowing of lines not matching the comment pragma regex in multiline comments containing comment pragma lines. Previously, these comments were dumped without being reindented to the result. Reviewers: djasper, mprobst Reviewed By: mprobst Subscribers: klimek, mprobst, cfe-commits Differential Revision: https://reviews.llvm.org/D30697 Modified: cfe/trunk/lib/Format/BreakableToken.cpp cfe/trunk/lib/Format/BreakableToken.h cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/unittests/Format/FormatTestJS.cpp Modified: cfe/trunk/lib/Format/BreakableToken.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/BreakableToken.cpp?rev=297261&r1=297260&r2=297261&view=diff == --- cfe/trunk/lib/Format/BreakableToken.cpp (original) +++ cfe/trunk/lib/Format/BreakableToken.cpp Wed Mar 8 02:55:12 2017 @@ -200,7 +200,8 @@ BreakableStringLiteral::BreakableStringL BreakableToken::Split BreakableStringLiteral::getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const { + unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const { return getStringSplit(Line.substr(TailOffset), StartColumn + Prefix.size() + Postfix.size(), ColumnLimit, Style.TabWidth, Encoding); @@ -231,9 +232,13 @@ BreakableComment::BreakableComment(const unsigned BreakableComment::getLineCount() const { return Lines.size(); } -BreakableToken::Split BreakableComment::getSplit(unsigned LineIndex, - unsigned TailOffset, - unsigned ColumnLimit) const { +BreakableToken::Split +BreakableComment::getSplit(unsigned LineIndex, unsigned TailOffset, + unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const { + // Don't break lines matching the comment pragmas regex. + if (CommentPragmasRegex.match(Content[LineIndex])) +return Split(StringRef::npos, 0); return getCommentSplit(Content[LineIndex].substr(TailOffset), getContentStartColumn(LineIndex, TailOffset), ColumnLimit, Style.TabWidth, Encoding); Modified: cfe/trunk/lib/Format/BreakableToken.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/BreakableToken.h?rev=297261&r1=297260&r2=297261&view=diff == --- cfe/trunk/lib/Format/BreakableToken.h (original) +++ cfe/trunk/lib/Format/BreakableToken.h Wed Mar 8 02:55:12 2017 @@ -90,7 +90,8 @@ public: /// \p LineIndex, if previously broken at \p TailOffset. If possible, do not /// violate \p ColumnLimit. virtual Split getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const = 0; + unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const = 0; /// \brief Emits the previously retrieved \p Split via \p Whitespaces. virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split, @@ -198,8 +199,8 @@ public: bool InPPDirective, encoding::Encoding Encoding, const FormatStyle &Style); - Split getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const override; + Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const override; void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split, WhitespaceManager &Whitespaces) override; void compressWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split, @@ -218,8 +219,8 @@ protected: public: unsigned getLineCount() const override; - Split getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const override; + Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const override; void compressWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split, WhitespaceManager &Whitespaces) override; Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=297261&r1=297260&r2=297261&view=diff == --- cfe/trunk/lib/Format/ContinuationIndent
[PATCH] D30697: [clang-format] Enable comment reflowing in multiline comments containing pragmas
This revision was automatically updated to reflect the committed changes. Closed by commit rL297261: [clang-format] Enable comment reflowing in multiline comments containing pragmas (authored by krasimir). Changed prior to commit: https://reviews.llvm.org/D30697?vs=90864&id=90984#toc Repository: rL LLVM https://reviews.llvm.org/D30697 Files: cfe/trunk/lib/Format/BreakableToken.cpp cfe/trunk/lib/Format/BreakableToken.h cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/unittests/Format/FormatTestJS.cpp Index: cfe/trunk/lib/Format/BreakableToken.cpp === --- cfe/trunk/lib/Format/BreakableToken.cpp +++ cfe/trunk/lib/Format/BreakableToken.cpp @@ -200,7 +200,8 @@ BreakableToken::Split BreakableStringLiteral::getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const { + unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const { return getStringSplit(Line.substr(TailOffset), StartColumn + Prefix.size() + Postfix.size(), ColumnLimit, Style.TabWidth, Encoding); @@ -231,9 +232,13 @@ unsigned BreakableComment::getLineCount() const { return Lines.size(); } -BreakableToken::Split BreakableComment::getSplit(unsigned LineIndex, - unsigned TailOffset, - unsigned ColumnLimit) const { +BreakableToken::Split +BreakableComment::getSplit(unsigned LineIndex, unsigned TailOffset, + unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const { + // Don't break lines matching the comment pragmas regex. + if (CommentPragmasRegex.match(Content[LineIndex])) +return Split(StringRef::npos, 0); return getCommentSplit(Content[LineIndex].substr(TailOffset), getContentStartColumn(LineIndex, TailOffset), ColumnLimit, Style.TabWidth, Encoding); Index: cfe/trunk/lib/Format/ContinuationIndenter.cpp === --- cfe/trunk/lib/Format/ContinuationIndenter.cpp +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp @@ -1183,7 +1183,6 @@ } } else if (Current.is(TT_BlockComment)) { if (!Current.isTrailingComment() || !Style.ReflowComments || -CommentPragmasRegex.match(Current.TokenText.substr(2)) || // If a comment token switches formatting, like // /* clang-format on */, we don't want to break it further, // but we may still want to adjust its indentation. @@ -1234,8 +1233,8 @@ RemainingTokenColumns = Token->getLineLengthAfterSplitBefore( LineIndex, TailOffset, RemainingTokenColumns, ColumnLimit, SplitBefore); while (RemainingTokenColumns > RemainingSpace) { - BreakableToken::Split Split = - Token->getSplit(LineIndex, TailOffset, ColumnLimit); + BreakableToken::Split Split = Token->getSplit( + LineIndex, TailOffset, ColumnLimit, CommentPragmasRegex); if (Split.first == StringRef::npos) { // The last line's penalty is handled in addNextStateToQueue(). if (LineIndex < EndIndex - 1) Index: cfe/trunk/lib/Format/BreakableToken.h === --- cfe/trunk/lib/Format/BreakableToken.h +++ cfe/trunk/lib/Format/BreakableToken.h @@ -90,7 +90,8 @@ /// \p LineIndex, if previously broken at \p TailOffset. If possible, do not /// violate \p ColumnLimit. virtual Split getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const = 0; + unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const = 0; /// \brief Emits the previously retrieved \p Split via \p Whitespaces. virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split, @@ -198,8 +199,8 @@ bool InPPDirective, encoding::Encoding Encoding, const FormatStyle &Style); - Split getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const override; + Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const override; void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split, WhitespaceManager &Whitespaces) override; void compressWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split, @@ -218,8 +219,8 @@ public: unsigned getLineCount() const override; - Split getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const override; + Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit, + llvm::
r297262 - [clang-format] Reformat BreakableToken.h; NFC
Author: krasimir Date: Wed Mar 8 02:58:44 2017 New Revision: 297262 URL: http://llvm.org/viewvc/llvm-project?rev=297262&view=rev Log: [clang-format] Reformat BreakableToken.h; NFC Modified: cfe/trunk/lib/Format/BreakableToken.h Modified: cfe/trunk/lib/Format/BreakableToken.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/BreakableToken.h?rev=297262&r1=297261&r2=297262&view=diff == --- cfe/trunk/lib/Format/BreakableToken.h (original) +++ cfe/trunk/lib/Format/BreakableToken.h Wed Mar 8 02:58:44 2017 @@ -118,10 +118,9 @@ public: /// /// A result having offset == StringRef::npos means that no piece of the line /// needs to be reformatted before any breaks are made. - virtual Split getSplitBefore(unsigned LineIndex, - unsigned PreviousEndColumn, + virtual Split getSplitBefore(unsigned LineIndex, unsigned PreviousEndColumn, unsigned ColumnLimit, - llvm::Regex& CommentPragmasRegex) const { + llvm::Regex &CommentPragmasRegex) const { return Split(StringRef::npos, 0); } @@ -130,10 +129,10 @@ public: /// \p SplitBefore has been reformatted, but before any breaks are made to /// this line. virtual unsigned getLineLengthAfterSplitBefore(unsigned LineIndex, - unsigned TailOffset, - unsigned PreviousEndColumn, - unsigned ColumnLimit, - Split SplitBefore) const { + unsigned TailOffset, + unsigned PreviousEndColumn, + unsigned ColumnLimit, + Split SplitBefore) const { return getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos); } @@ -142,8 +141,7 @@ public: /// whitespace range \p SplitBefore. virtual void replaceWhitespaceBefore(unsigned LineIndex, unsigned PreviousEndColumn, - unsigned ColumnLimit, - Split SplitBefore, + unsigned ColumnLimit, Split SplitBefore, WhitespaceManager &Whitespaces) {} /// \brief Updates the next token of \p State to the next token after this @@ -291,8 +289,7 @@ public: bool InPPDirective, encoding::Encoding Encoding, const FormatStyle &Style); - unsigned getLineLengthAfterSplit(unsigned LineIndex, - unsigned TailOffset, + unsigned getLineLengthAfterSplit(unsigned LineIndex, unsigned TailOffset, StringRef::size_type Length) const override; void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split, WhitespaceManager &Whitespaces) override; @@ -305,8 +302,7 @@ public: unsigned ColumnLimit, Split SplitBefore) const override; void replaceWhitespaceBefore(unsigned LineIndex, unsigned PreviousEndColumn, - unsigned ColumnLimit, - Split SplitBefore, + unsigned ColumnLimit, Split SplitBefore, WhitespaceManager &Whitespaces) override; bool mayReflow(unsigned LineIndex, llvm::Regex &CommentPragmasRegex) const override; @@ -324,8 +320,7 @@ private: // Computes the end column if the full Content from LineIndex gets reflown // after PreviousEndColumn. - unsigned getReflownColumn(StringRef Content, -unsigned LineIndex, + unsigned getReflownColumn(StringRef Content, unsigned LineIndex, unsigned PreviousEndColumn) const; unsigned getContentStartColumn(unsigned LineIndex, @@ -362,22 +357,22 @@ public: bool InPPDirective, encoding::Encoding Encoding, const FormatStyle &Style); - unsigned getLineLengthAfterSplit(unsigned LineIndex, - unsigned TailOffset, + unsigned getLineLengthAfterSplit(unsigned LineIndex, unsigned TailOffset, StringRef::size_type Length) const override; void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split, WhitespaceManager &Whitespaces) override; Split getSplitBefore(unsigned LineIndex, unsigned PreviousEndColumn, unsigned ColumnLimit, llvm::Regex &CommentPragmasRegex) const override; - unsigned getLin
r297263 - [clang-format] Fix parameter name comment; NFC
Author: krasimir Date: Wed Mar 8 03:02:39 2017 New Revision: 297263 URL: http://llvm.org/viewvc/llvm-project?rev=297263&view=rev Log: [clang-format] Fix parameter name comment; NFC Modified: cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp Modified: cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp?rev=297263&r1=297262&r2=297263&view=diff == --- cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp (original) +++ cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp Wed Mar 8 03:02:39 2017 @@ -908,7 +908,7 @@ void UnwrappedLineFormatter::formatFirst if (RootToken.is(tok::eof)) { unsigned Newlines = std::min(RootToken.NewlinesBefore, 1u); Whitespaces->replaceWhitespace(RootToken, Newlines, /*Spaces=*/0, - /*TargetColumn=*/0); + /*StartOfTokenColumn=*/0); return; } unsigned Newlines = ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30685: [include-fixer] Remove line number from Symbol identity
hokein added a comment. > We may want to track individual occurrences (line number, full type info) > and aggregate this during mapreduce, but that's not done here. Seems reasonable. So we will introduce a new structure to track these occurrences? Or reuse the `SymbolInfo::Signals`? Comment at: unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp:45 - bool hasSymbol(const SymbolInfo &Symbol) const { + int hasSymbol(const SymbolInfo &Symbol) const { auto it = Symbols.find(Symbol); With the change, the name is not a suitable name as it returns to the number of times. Maybe rename it ("symbolSeenTimes"). The same below. https://reviews.llvm.org/D30685 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297264 - [test] Unbreak OpenMP/linking.c with arch-specific libdir
Author: hahnfeld Date: Wed Mar 8 03:07:33 2017 New Revision: 297264 URL: http://llvm.org/viewvc/llvm-project?rev=297264&view=rev Log: [test] Unbreak OpenMP/linking.c with arch-specific libdir After rL296927, -rpath gets added after linking the OpenMP runtime. That's why -lgcc does not immediately follow -lomp or -lgomp. Modified: cfe/trunk/test/OpenMP/linking.c Modified: cfe/trunk/test/OpenMP/linking.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/linking.c?rev=297264&r1=297263&r2=297264&view=diff == --- cfe/trunk/test/OpenMP/linking.c (original) +++ cfe/trunk/test/OpenMP/linking.c Wed Mar 8 03:07:33 2017 @@ -7,42 +7,42 @@ // RUN: -fopenmp -target i386-unknown-linux -rtlib=platform \ // RUN: | FileCheck --check-prefix=CHECK-LD-32 %s // CHECK-LD-32: "{{.*}}ld{{(.exe)?}}" -// CHECK-LD-32: "-l[[DEFAULT_OPENMP_LIB:[^"]*]]" "-lgcc" +// CHECK-LD-32: "-l[[DEFAULT_OPENMP_LIB:[^"]*]]" // CHECK-LD-32: "-lpthread" "-lc" // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -fopenmp -target x86_64-unknown-linux -rtlib=platform \ // RUN: | FileCheck --check-prefix=CHECK-LD-64 %s // CHECK-LD-64: "{{.*}}ld{{(.exe)?}}" -// CHECK-LD-64: "-l[[DEFAULT_OPENMP_LIB:[^"]*]]" "-lgcc" +// CHECK-LD-64: "-l[[DEFAULT_OPENMP_LIB:[^"]*]]" // CHECK-LD-64: "-lpthread" "-lc" // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -fopenmp=libgomp -target i386-unknown-linux -rtlib=platform \ // RUN: | FileCheck --check-prefix=CHECK-GOMP-LD-32 %s // CHECK-GOMP-LD-32: "{{.*}}ld{{(.exe)?}}" -// CHECK-GOMP-LD-32: "-lgomp" "-lrt" "-lgcc" +// CHECK-GOMP-LD-32: "-lgomp" "-lrt" // CHECK-GOMP-LD-32: "-lpthread" "-lc" // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -fopenmp=libgomp -target x86_64-unknown-linux -rtlib=platform \ // RUN: | FileCheck --check-prefix=CHECK-GOMP-LD-64 %s // CHECK-GOMP-LD-64: "{{.*}}ld{{(.exe)?}}" -// CHECK-GOMP-LD-64: "-lgomp" "-lrt" "-lgcc" +// CHECK-GOMP-LD-64: "-lgomp" "-lrt" // CHECK-GOMP-LD-64: "-lpthread" "-lc" // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -fopenmp -target i386-unknown-linux -rtlib=platform \ // RUN: | FileCheck --check-prefix=CHECK-IOMP5-LD-32 %s // CHECK-IOMP5-LD-32: "{{.*}}ld{{(.exe)?}}" -// CHECK-IOMP5-LD-32: "-l[[DEFAULT_OPENMP_LIB:[^"]*]]" "-lgcc" +// CHECK-IOMP5-LD-32: "-l[[DEFAULT_OPENMP_LIB:[^"]*]]" // CHECK-IOMP5-LD-32: "-lpthread" "-lc" // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -fopenmp -target x86_64-unknown-linux -rtlib=platform \ // RUN: | FileCheck --check-prefix=CHECK-IOMP5-LD-64 %s // CHECK-IOMP5-LD-64: "{{.*}}ld{{(.exe)?}}" -// CHECK-IOMP5-LD-64: "-l[[DEFAULT_OPENMP_LIB:[^"]*]]" "-lgcc" +// CHECK-IOMP5-LD-64: "-l[[DEFAULT_OPENMP_LIB:[^"]*]]" // CHECK-IOMP5-LD-64: "-lpthread" "-lc" // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ @@ -60,7 +60,7 @@ // RUN: -rtlib=platform \ // RUN: | FileCheck --check-prefix=CHECK-LD-OVERRIDE-32 %s // CHECK-LD-OVERRIDE-32: "{{.*}}ld{{(.exe)?}}" -// CHECK-LD-OVERRIDE-32: "-lgomp" "-lrt" "-lgcc" +// CHECK-LD-OVERRIDE-32: "-lgomp" "-lrt" // CHECK-LD-OVERRIDE-32: "-lpthread" "-lc" // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ @@ -68,7 +68,7 @@ // RUN: -rtlib=platform \ // RUN: | FileCheck --check-prefix=CHECK-LD-OVERRIDE-64 %s // CHECK-LD-OVERRIDE-64: "{{.*}}ld{{(.exe)?}}" -// CHECK-LD-OVERRIDE-64: "-lgomp" "-lrt" "-lgcc" +// CHECK-LD-OVERRIDE-64: "-lgomp" "-lrt" // CHECK-LD-OVERRIDE-64: "-lpthread" "-lc" // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297265 - [clang-format] Fixed a typo in Format.cpp and a clang-tidy nit about std::function copying; NFC
Author: krasimir Date: Wed Mar 8 03:13:25 2017 New Revision: 297265 URL: http://llvm.org/viewvc/llvm-project?rev=297265&view=rev Log: [clang-format] Fixed a typo in Format.cpp and a clang-tidy nit about std::function copying; NFC Modified: cfe/trunk/lib/Format/Format.cpp Modified: cfe/trunk/lib/Format/Format.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=297265&r1=297264&r2=297265&view=diff == --- cfe/trunk/lib/Format/Format.cpp (original) +++ cfe/trunk/lib/Format/Format.cpp Wed Mar 8 03:13:25 2017 @@ -1552,8 +1552,8 @@ inline bool isHeaderDeletion(const tooli // tokens and returns an offset after the sequence. unsigned getOffsetAfterTokenSequence( StringRef FileName, StringRef Code, const FormatStyle &Style, -std::function -GetOffsetAfterSequense) { +llvm::function_ref +GetOffsetAfterSequence) { std::unique_ptr Env = Environment::CreateVirtualEnvironment(Code, FileName, /*Ranges=*/{}); const SourceManager &SourceMgr = Env->getSourceManager(); @@ -1562,7 +1562,7 @@ unsigned getOffsetAfterTokenSequence( Token Tok; // Get the first token. Lex.LexFromRawLexer(Tok); - return GetOffsetAfterSequense(SourceMgr, Lex, Tok); + return GetOffsetAfterSequence(SourceMgr, Lex, Tok); } // Check if a sequence of tokens is like "# ". If it is, ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297266 - [scan-build-py] fix some line separator issues
Author: rizsotto Date: Wed Mar 8 03:27:53 2017 New Revision: 297266 URL: http://llvm.org/viewvc/llvm-project?rev=297266&view=rev Log: [scan-build-py] fix some line separator issues Differential Revision: https://reviews.llvm.org/D30600 Modified: cfe/trunk/tools/scan-build-py/libear/__init__.py cfe/trunk/tools/scan-build-py/libscanbuild/report.py Modified: cfe/trunk/tools/scan-build-py/libear/__init__.py URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build-py/libear/__init__.py?rev=297266&r1=297265&r2=297266&view=diff == --- cfe/trunk/tools/scan-build-py/libear/__init__.py (original) +++ cfe/trunk/tools/scan-build-py/libear/__init__.py Wed Mar 8 03:27:53 2017 @@ -207,9 +207,9 @@ class Configure(object): if m: key = m.group(1) if key not in definitions or not definitions[key]: -return '/* #undef {} */\n'.format(key) +return '/* #undef {0} */{1}'.format(key, os.linesep) else: -return '#define {}\n'.format(key) +return '#define {0}{1}'.format(key, os.linesep) return line with open(template, 'r') as src_handle: Modified: cfe/trunk/tools/scan-build-py/libscanbuild/report.py URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build-py/libscanbuild/report.py?rev=297266&r1=297265&r2=297266&view=diff == --- cfe/trunk/tools/scan-build-py/libscanbuild/report.py (original) +++ cfe/trunk/tools/scan-build-py/libscanbuild/report.py Wed Mar 8 03:27:53 2017 @@ -336,11 +336,12 @@ def parse_crash(filename): match = re.match(r'(.*)\.info\.txt', filename) name = match.group(1) if match else None -with open(filename) as handler: -lines = handler.readlines() +with open(filename, mode='rb') as handler: +# this is a workaround to fix windows read '\r\n' as new lines. +lines = [line.decode().rstrip() for line in handler.readlines()] return { -'source': lines[0].rstrip(), -'problem': lines[1].rstrip(), +'source': lines[0], +'problem': lines[1], 'file': name, 'info': name + '.info.txt', 'stderr': name + '.stderr.txt' ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30705: clang-format: [JS] allow breaking after non-null assertions.
djasper accepted this revision. djasper added inline comments. This revision is now accepted and ready to land. Comment at: lib/Format/TokenAnnotator.cpp:1056 +} else if (Current.is(tok::exclaim)) { + if (Style.Language == FormatStyle::LK_JavaScript) { +if (Current.Previous && I wonder whether we should do this logic "inside out", i.e. have language-specific parts at the top (or in a separate function). We have started that in mustBreakBefore and I think that's helpful. I can do this in a follow-up, though. Comment at: lib/Format/TokenAnnotator.cpp:1063 + return; +} else if (Current.Next && + Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) { No "else" after "return": http://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return https://reviews.llvm.org/D30705 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30087: [Driver] Unify linking of OpenMP runtime
Hahnfeld updated this revision to Diff 90987. Hahnfeld added a comment. Rebase for recent refactoring and ping. https://reviews.llvm.org/D30087 Files: lib/Driver/ToolChains/CommonArgs.cpp lib/Driver/ToolChains/CommonArgs.h lib/Driver/ToolChains/Darwin.cpp lib/Driver/ToolChains/FreeBSD.cpp lib/Driver/ToolChains/Gnu.cpp lib/Driver/ToolChains/NetBSD.cpp test/Driver/fopenmp.c Index: test/Driver/fopenmp.c === --- test/Driver/fopenmp.c +++ test/Driver/fopenmp.c @@ -18,29 +18,33 @@ // CHECK-CC1-NO-OPENMP-NOT: "-fopenmp" // // RUN: %clang -target x86_64-linux-gnu -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP -// RUN: %clang -target x86_64-linux-gnu -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP +// RUN: %clang -target x86_64-linux-gnu -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-RT // RUN: %clang -target x86_64-linux-gnu -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 // // RUN: %clang -nostdlib -target x86_64-linux-gnu -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP // RUN: %clang -nostdlib -target x86_64-linux-gnu -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP // RUN: %clang -nostdlib -target x86_64-linux-gnu -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 // // RUN: %clang -target x86_64-darwin -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP -// RUN: %clang -target x86_64-darwin -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP +// RUN: %clang -target x86_64-darwin -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT // RUN: %clang -target x86_64-darwin -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 // // RUN: %clang -nostdlib -target x86_64-darwin -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP // RUN: %clang -nostdlib -target x86_64-darwin -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP // RUN: %clang -nostdlib -target x86_64-darwin -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 // -// RUN: %clang -target x86_64-netbsd -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP -// RUN: %clang -target x86_64-netbsd -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP -// RUN: %clang -target x86_64-netbsd -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 +// RUN: %clang -target x86_64-freebsd -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP +// RUN: %clang -target x86_64-freebsd -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT +// RUN: %clang -target x86_64-freebsd -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 // // RUN: %clang -nostdlib -target x86_64-freebsd -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP // RUN: %clang -nostdlib -target x86_64-freebsd -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP // RUN: %clang -nostdlib -target x86_64-freebsd -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 // +// RUN: %clang -target x86_64-netbsd -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-OMP +// RUN: %clang -target x86_64-netbsd -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-GOMP --check-prefix=CHECK-LD-GOMP-NO-RT +// RUN: %clang -target x86_64-netbsd -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-LD-IOMP5 +// // RUN: %clang -nostdlib -target x86_64-netbsd -fopenmp=libomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP // RUN: %clang -nostdlib -target x86_64-netbsd -fopenmp=libgomp %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-GOMP // RUN: %clang -nostdlib -target x86_64-netbsd -fopenmp=libiomp5 %s -o %t -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-IOMP5 @@ -50,6 +54,8 @@ // // CHECK-LD-GOMP: "{{.*}}ld{{(.exe)?}}" // CHECK-LD-GOMP: "-lgomp" +// CHECK-LD-GOMP-RT: "-lrt" +// CHECK-LD-GOMP-NO-RT-NOT: "-lrt" // // CHECK-LD-IOMP5: "{{.*}}ld{{(.exe)?}}" // CHECK-LD-IOMP5: "-liomp5" Index: lib/Driver/ToolChains/NetBSD.cpp === --- lib/Driver/ToolChains/NetBSD.cpp +++ lib/Driver/ToolChains/NetBSD.cpp @@ -274,7 +274,7 @@ } if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { -addOpenMPRuntime(CmdArgs, getToolChain(), Args); +addOpenMPRuntime(CmdArgs, getToolChain(), Args, JA); if (D.CCCIsCXX()) {
[PATCH] D27810: FileManager: mark virtual file entries as valid entries
erikjv added a comment. @kfunk yes and yes, so @bkramer or @klimek : ping? https://reviews.llvm.org/D27810 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
cfe-commits@lists.llvm.org
Author: djasper Date: Wed Mar 8 03:49:12 2017 New Revision: 297268 URL: http://llvm.org/viewvc/llvm-project?rev=297268&view=rev Log: clang-format: Get slightly better at understanding */&. Before: void f() { MACRO(A * const a); } After: void f() { MACRO(A *const a); } Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=297268&r1=297267&r2=297268&view=diff == --- cfe/trunk/lib/Format/TokenAnnotator.cpp (original) +++ cfe/trunk/lib/Format/TokenAnnotator.cpp Wed Mar 8 03:49:12 2017 @@ -1302,7 +1302,8 @@ private: return TT_UnaryOperator; const FormatToken *NextToken = Tok.getNextNonComment(); -if (!NextToken || NextToken->isOneOf(tok::arrow, tok::equal) || +if (!NextToken || +NextToken->isOneOf(tok::arrow, tok::equal, tok::kw_const) || (NextToken->is(tok::l_brace) && !NextToken->getNextNonComment())) return TT_PointerOrReference; Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=297268&r1=297267&r2=297268&view=diff == --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Wed Mar 8 03:49:12 2017 @@ -4965,6 +4965,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStar verifyIndependentOfContext("MACRO(int *i);"); verifyIndependentOfContext("MACRO(auto *a);"); verifyIndependentOfContext("MACRO(const A *a);"); + verifyIndependentOfContext("MACRO(A *const a);"); verifyIndependentOfContext("MACRO('0' <= c && c <= '9');"); verifyFormat("void f() { f(float{1}, a * a); }"); // FIXME: Is there a way to make this work? ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30705: clang-format: [JS] allow breaking after non-null assertions.
mprobst marked 2 inline comments as done. mprobst added inline comments. Comment at: lib/Format/TokenAnnotator.cpp:1056 +} else if (Current.is(tok::exclaim)) { + if (Style.Language == FormatStyle::LK_JavaScript) { +if (Current.Previous && djasper wrote: > I wonder whether we should do this logic "inside out", i.e. have > language-specific parts at the top (or in a separate function). We have > started that in mustBreakBefore and I think that's helpful. > > I can do this in a follow-up, though. Yeah, I was debating that but wanted to stick with the code style. Done. https://reviews.llvm.org/D30705 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30705: clang-format: [JS] allow breaking after non-null assertions.
mprobst updated this revision to Diff 90988. mprobst marked an inline comment as done. mprobst added a comment. - Introduce TT_JsNonNullAssertion to centralize determining token types. - Move up language specific code in determineTokenType. https://reviews.llvm.org/D30705 Files: lib/Format/FormatToken.h lib/Format/TokenAnnotator.cpp unittests/Format/FormatTestJS.cpp Index: unittests/Format/FormatTestJS.cpp === --- unittests/Format/FormatTestJS.cpp +++ unittests/Format/FormatTestJS.cpp @@ -1679,6 +1679,12 @@ verifyFormat("let x = (foo)!;\n"); verifyFormat("let x = foo! - 1;\n"); verifyFormat("let x = {foo: 1}!;\n"); + verifyFormat( + "let x = hello.foo()!\n" + ".foo()!\n" + ".foo()!\n" + ".foo()!;\n", + getGoogleJSStyleWithColumns(20)); } TEST_F(FormatTestJS, Conditional) { Index: lib/Format/TokenAnnotator.cpp === --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -1024,6 +1024,23 @@ // The token type is already known. return; +if (Style.Language == FormatStyle::LK_JavaScript) { + if (Current.is(tok::exclaim)) { +if (Current.Previous && +(Current.Previous->isOneOf(tok::identifier, tok::r_paren, + tok::r_square, tok::r_brace) || + Current.Previous->Tok.isLiteral())) { + Current.Type = TT_JsNonNullAssertion; + return; +} +if (Current.Next && +Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) { + Current.Type = TT_JsNonNullAssertion; + return; +} + } +} + // Line.MightBeFunctionDecl can only be true after the parentheses of a // function declaration have been found. In this case, 'Current' is a // trailing token of this declaration and thus cannot be a name. @@ -2277,12 +2294,9 @@ // locations that should have whitespace following are identified by the // above set of follower tokens. return false; -// Postfix non-null assertion operator, as in `foo!.bar()`. -if (Right.is(tok::exclaim) && (Left.isOneOf(tok::identifier, tok::r_paren, -tok::r_square, tok::r_brace) || - Left.Tok.isLiteral())) +if (Right.is(TT_JsNonNullAssertion)) return false; -if (Left.is(tok::exclaim) && Right.is(Keywords.kw_as)) +if (Left.is(TT_JsNonNullAssertion) && Right.is(Keywords.kw_as)) return true; // "x! as string" } else if (Style.Language == FormatStyle::LK_Java) { if (Left.is(tok::r_square) && Right.is(tok::l_brace)) @@ -2535,6 +2549,8 @@ return false; // must not break before as in 'x as type' casts if (Left.is(Keywords.kw_as)) return true; +if (Left.is(TT_JsNonNullAssertion)) + return true; if (Left.is(Keywords.kw_declare) && Right.isOneOf(Keywords.kw_module, tok::kw_namespace, Keywords.kw_function, tok::kw_class, tok::kw_enum, Index: lib/Format/FormatToken.h === --- lib/Format/FormatToken.h +++ lib/Format/FormatToken.h @@ -53,6 +53,7 @@ TYPE(JavaAnnotation) \ TYPE(JsComputedPropertyName) \ TYPE(JsFatArrow) \ + TYPE(JsNonNullAssertion) \ TYPE(JsTypeColon) \ TYPE(JsTypeOperator) \ TYPE(JsTypeOptionalQuestion) \ Index: unittests/Format/FormatTestJS.cpp === --- unittests/Format/FormatTestJS.cpp +++ unittests/Format/FormatTestJS.cpp @@ -1679,6 +1679,12 @@ verifyFormat("let x = (foo)!;\n"); verifyFormat("let x = foo! - 1;\n"); verifyFormat("let x = {foo: 1}!;\n"); + verifyFormat( + "let x = hello.foo()!\n" + ".foo()!\n" + ".foo()!\n" + ".foo()!;\n", + getGoogleJSStyleWithColumns(20)); } TEST_F(FormatTestJS, Conditional) { Index: lib/Format/TokenAnnotator.cpp === --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -1024,6 +1024,23 @@ // The token type is already known. return; +if (Style.Language == FormatStyle::LK_JavaScript) { + if (Current.is(tok::exclaim)) { +if (Current.Previous && +(Current.Previous->isOneOf(tok::identifier, tok::r_paren, + tok::r_square, tok::r_brace) || + Current.Previous->Tok.isLiteral())) { + Current.Type = TT_JsNonNullAssertion; + return; +} +if (Current.Next && +Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) { + Current.Type = TT_JsNonNullAssertion; + return; +} + } +} + // Line.MightBeF
[PATCH] D30685: [include-fixer] Remove line number from Symbol identity
sammccall updated this revision to Diff 90990. sammccall added a comment. Address review comments. Uncovered two bugs: - accidentally casting through bool: EXPECT_EQ(1, hasSymbol) was a lie - we were double counting uses of typedefs where the underlying type was built in, because qualType(hasDeclaration) stops at the typedef in this case. https://reviews.llvm.org/D30685 Files: include-fixer/IncludeFixer.cpp include-fixer/find-all-symbols/FindAllMacros.cpp include-fixer/find-all-symbols/FindAllSymbols.cpp include-fixer/find-all-symbols/SymbolInfo.cpp include-fixer/find-all-symbols/SymbolInfo.h include-fixer/tool/ClangIncludeFixer.cpp test/include-fixer/Inputs/fake_yaml_db.yaml test/include-fixer/Inputs/merge/a.yaml test/include-fixer/Inputs/merge/b.yaml test/include-fixer/merge.test unittests/include-fixer/IncludeFixerTest.cpp unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp Index: unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp === --- unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp +++ unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp @@ -42,27 +42,25 @@ Symbols[Entry.first] += Entry.second; } - bool hasSymbol(const SymbolInfo &Symbol) const { + int seen(const SymbolInfo &Symbol) const { auto it = Symbols.find(Symbol); -return it != Symbols.end() && it->second.Seen > 0; +return it == Symbols.end() ? 0 : it->second.Seen; } - bool hasUse(const SymbolInfo &Symbol) const { + int used(const SymbolInfo &Symbol) const { auto it = Symbols.find(Symbol); -return it != Symbols.end() && it->second.Used > 0; +return it == Symbols.end() ? 0 : it->second.Used; } private: SymbolInfo::SignalMap Symbols; }; class FindAllSymbolsTest : public ::testing::Test { public: - bool hasSymbol(const SymbolInfo &Symbol) { -return Reporter.hasSymbol(Symbol); - } + int seen(const SymbolInfo &Symbol) { return Reporter.seen(Symbol); } - bool hasUse(const SymbolInfo &Symbol) { return Reporter.hasUse(Symbol); } + int used(const SymbolInfo &Symbol) { return Reporter.used(Symbol); } bool runFindAllSymbols(StringRef HeaderCode, StringRef MainCode) { llvm::IntrusiveRefCntPtr InMemoryFileSystem( @@ -86,9 +84,9 @@ std::string InternalCode = "#include \"private.inc\"\nclass Internal {};"; SymbolInfo InternalSymbol("Internal", SymbolInfo::SymbolKind::Class, - TopHeader, 2, {}); + TopHeader, {}); SymbolInfo IncSymbol("IncHeaderClass", SymbolInfo::SymbolKind::Class, - TopHeader, 1, {}); + TopHeader, {}); InMemoryFileSystem->addFile( IncHeader, 0, llvm::MemoryBuffer::getMemBuffer(IncHeaderCode)); InMemoryFileSystem->addFile(InternalHeader, 0, @@ -120,19 +118,19 @@ InMemoryFileSystem->addFile( DirtyHeader, 0, llvm::MemoryBuffer::getMemBuffer(DirtyHeaderContent)); SymbolInfo DirtyMacro("INTERNAL", SymbolInfo::SymbolKind::Macro, - CleanHeader, 1, {}); + CleanHeader, {}); SymbolInfo DirtySymbol("ExtraInternal", SymbolInfo::SymbolKind::Class, - CleanHeader, 2, {}); + CleanHeader, {}); #endif // _MSC_VER && __MINGW32__ Content += "\n" + MainCode.str(); InMemoryFileSystem->addFile(FileName, 0, llvm::MemoryBuffer::getMemBuffer(Content)); Invocation.run(); -EXPECT_TRUE(hasSymbol(InternalSymbol)); -EXPECT_TRUE(hasSymbol(IncSymbol)); +EXPECT_EQ(1, seen(InternalSymbol)); +EXPECT_EQ(1, seen(IncSymbol)); #if !defined(_MSC_VER) && !defined(__MINGW32__) -EXPECT_TRUE(hasSymbol(DirtySymbol)); -EXPECT_TRUE(hasSymbol(DirtyMacro)); +EXPECT_EQ(1, seen(DirtySymbol)); +EXPECT_EQ(1, seen(DirtyMacro)); #endif // _MSC_VER && __MINGW32__ return true; } @@ -155,20 +153,20 @@ runFindAllSymbols(Header, Main); SymbolInfo Symbol = - SymbolInfo("xargc", SymbolInfo::SymbolKind::Variable, HeaderName, 2, {}); - EXPECT_TRUE(hasSymbol(Symbol)); - EXPECT_TRUE(hasUse(Symbol)); + SymbolInfo("xargc", SymbolInfo::SymbolKind::Variable, HeaderName, {}); + EXPECT_EQ(1, seen(Symbol)); + EXPECT_EQ(1, used(Symbol)); - Symbol = SymbolInfo("", SymbolInfo::SymbolKind::Variable, HeaderName, 4, + Symbol = SymbolInfo("", SymbolInfo::SymbolKind::Variable, HeaderName, {{SymbolInfo::ContextType::Namespace, "na"}}); - EXPECT_TRUE(hasSymbol(Symbol)); - EXPECT_TRUE(hasUse(Symbol)); + EXPECT_EQ(1, seen(Symbol)); + EXPECT_EQ(1, used(Symbol)); - Symbol = SymbolInfo("", SymbolInfo::SymbolKind::Variable, HeaderName, 5, + Symbol = SymbolInfo("", SymbolInfo::SymbolKind::Variable, HeaderName, {{SymbolInfo::ContextType::Namespace
[PATCH] D30685: [include-fixer] Remove line number from Symbol identity
sammccall marked an inline comment as done. sammccall added a comment. In https://reviews.llvm.org/D30685#695284, @hokein wrote: > > We may want to track individual occurrences (line number, full type info) > > and aggregate this during mapreduce, but that's not done here. > > Seems reasonable. So we will introduce a new structure to track these > occurrences? Or reuse the `SymbolInfo::Signals`? These aren't really signals, but they're more like map-value than map-key. I suspect it's another new struct. Fortunately we don't actually need it yet. https://reviews.llvm.org/D30685 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27810: FileManager: mark virtual file entries as valid entries
bkramer added a comment. I assume this is fine but I don't really understand what's going on. A test case would be great. https://reviews.llvm.org/D27810 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27810: FileManager: mark virtual file entries as valid entries
klimek added a comment. Is the diff view on phab broken, or am I missing something? I only see a single line of diff now, and don't see a way to change the diff. https://reviews.llvm.org/D27810 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30575: [clang-format] Look at NoLineBreak and NoLineBreakInOperand before breakProtrudingToken
djasper added inline comments. Comment at: lib/Format/ContinuationIndenter.cpp:852 + bool CanBreakProtrudingToken = + State.Stack.empty() || (!State.Stack.back().NoLineBreak && + !State.Stack.back().NoLineBreakInOperand); I think we assume here and in many other place that the stack is never empty. E.g. there is no similar check in l.847 above. So, I'd remove this here, too. In the long run, we probably want to have a class properly wrapping the Stack. https://reviews.llvm.org/D30575 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27810: FileManager: mark virtual file entries as valid entries
erikjv added a comment. @klimek no, it's a 1 line fix. The rest was the previous version of the patch. https://reviews.llvm.org/D27810 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297271 - [XRay] Use AddCXXStdlibLibArgs. NFCI.
Author: hahnfeld Date: Wed Mar 8 06:06:44 2017 New Revision: 297271 URL: http://llvm.org/viewvc/llvm-project?rev=297271&view=rev Log: [XRay] Use AddCXXStdlibLibArgs. NFCI. This function already does the very same thing. Modified: cfe/trunk/lib/Driver/ToolChains/Gnu.cpp Modified: cfe/trunk/lib/Driver/ToolChains/Gnu.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Gnu.cpp?rev=297271&r1=297270&r2=297271&view=diff == --- cfe/trunk/lib/Driver/ToolChains/Gnu.cpp (original) +++ cfe/trunk/lib/Driver/ToolChains/Gnu.cpp Wed Mar 8 06:06:44 2017 @@ -347,10 +347,9 @@ static void linkXRayRuntimeDeps(const To CmdArgs.push_back("-lrt"); CmdArgs.push_back("-lm"); CmdArgs.push_back("-latomic"); - if (TC.GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) -CmdArgs.push_back("-lc++"); - else -CmdArgs.push_back("-lstdc++"); + + TC.AddCXXStdlibLibArgs(Args, CmdArgs); + if (TC.getTriple().getOS() != llvm::Triple::FreeBSD) CmdArgs.push_back("-ldl"); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30650: [clang-tidy] misc-use-after-move: Fix failing assertion
klimek added a comment. In https://reviews.llvm.org/D30650#693165, @Eugene.Zelenko wrote: > I think we should refactor this check as part of Static Analyzer, since it's > path-sensitive. Are you saying it should be path sensitive? Because currently it's not, right? https://reviews.llvm.org/D30650 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28820: Warn when calling a non interrupt function from an interrupt on ARM
tyomitch added a comment. When compiling for softfp targets, this new warning doesn't make sense: there are no VFP registers to save. Jonathan, would you please conditionalize it to only affect hardfp targets? https://reviews.llvm.org/D28820 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30700: [Driver] Always add arch-specific-subdir to -rpath
Hahnfeld added a comment. No build system will ever set `-frtlib-add-rpath` to enable this "feature". I'm for keeping this opt-out until we have configuration files to set this by default. Making it opt-in would weaken its main reason of existence: Not to break simple binaries for the user, and we can just drop it. https://reviews.llvm.org/D30700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30733: [Driver] Add arch-specific rpath for libc++
Hahnfeld created this revision. Herald added a reviewer: EricWF. libc++ may be installed there as a runtime library. https://reviews.llvm.org/D30733 Files: lib/Driver/ToolChain.cpp Index: lib/Driver/ToolChain.cpp === --- lib/Driver/ToolChain.cpp +++ lib/Driver/ToolChain.cpp @@ -648,6 +648,8 @@ switch (Type) { case ToolChain::CST_Libcxx: CmdArgs.push_back("-lc++"); +// libc++ may be installed per arch. +addArchSpecificRPath(*this, Args, CmdArgs); break; case ToolChain::CST_Libstdcxx: Index: lib/Driver/ToolChain.cpp === --- lib/Driver/ToolChain.cpp +++ lib/Driver/ToolChain.cpp @@ -648,6 +648,8 @@ switch (Type) { case ToolChain::CST_Libcxx: CmdArgs.push_back("-lc++"); +// libc++ may be installed per arch. +addArchSpecificRPath(*this, Args, CmdArgs); break; case ToolChain::CST_Libstdcxx: ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30675: [clangd] Fix not being able to attach a debugger on macOS
bkramer added a comment. Generally makes sense. Is there any reason for the #ifdef? Windows has errno and EINTR too. Repository: rL LLVM https://reviews.llvm.org/D30675 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30650: [clang-tidy] misc-use-after-move: Fix failing assertion
mboehme added a comment. In https://reviews.llvm.org/D30650#695350, @klimek wrote: > In https://reviews.llvm.org/D30650#693165, @Eugene.Zelenko wrote: > > > I think we should refactor this check as part of Static Analyzer, since > > it's path-sensitive. > > > Are you saying it should be path sensitive? Because currently it's not, right? (Will submit in the meantime because this is a wider discussion that doesn't impact this patch specifically. But let's continue the discussion.) https://reviews.llvm.org/D30650 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r297272 - [clang-tidy] misc-use-after-move: Fix failing assertion
Author: mboehme Date: Wed Mar 8 06:34:51 2017 New Revision: 297272 URL: http://llvm.org/viewvc/llvm-project?rev=297272&view=rev Log: [clang-tidy] misc-use-after-move: Fix failing assertion Summary: I've added a test case that (without the fix) triggers the assertion, which happens when a move happens in an implicitly called conversion operator. This patch also fixes nondeterministic behavior in the source code location reported for the move when the move is constained in an init list; this was causing buildbot failures in the previous attempt to submit this patch (see D30569 and rL297004). Reviewers: alexfh Reviewed By: alexfh Subscribers: Eugene.Zelenko, JDevlieghere, cfe-commits Differential Revision: https://reviews.llvm.org/D30650 Modified: clang-tools-extra/trunk/clang-tidy/misc/UseAfterMoveCheck.cpp clang-tools-extra/trunk/test/clang-tidy/misc-use-after-move.cpp Modified: clang-tools-extra/trunk/clang-tidy/misc/UseAfterMoveCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/UseAfterMoveCheck.cpp?rev=297272&r1=297271&r2=297272&view=diff == --- clang-tools-extra/trunk/clang-tidy/misc/UseAfterMoveCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/misc/UseAfterMoveCheck.cpp Wed Mar 8 06:34:51 2017 @@ -384,6 +384,13 @@ void UseAfterMoveCheck::registerMatchers // the direct ancestor of the std::move() that isn't one of the node // types ignored by ignoringParenImpCasts(). stmt(forEach(expr(ignoringParenImpCasts(CallMoveMatcher))), + // Don't allow an InitListExpr to be the moving call. An InitListExpr + // has both a syntactic and a semantic form, and the parent-child + // relationships are different between the two. This could cause an + // InitListExpr to be analyzed as the moving call in addition to the + // Expr that we actually want, resulting in two diagnostics with + // different code locations for the same move. + unless(initListExpr()), unless(expr(ignoringParenImpCasts(equalsBoundNode("call-move") .bind("moving-call"), this); @@ -398,7 +405,7 @@ void UseAfterMoveCheck::check(const Matc const auto *MovingCall = Result.Nodes.getNodeAs("moving-call"); const auto *Arg = Result.Nodes.getNodeAs("arg"); - if (!MovingCall) + if (!MovingCall || !MovingCall->getExprLoc().isValid()) MovingCall = CallMove; Stmt *FunctionBody = nullptr; Modified: clang-tools-extra/trunk/test/clang-tidy/misc-use-after-move.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-use-after-move.cpp?rev=297272&r1=297271&r2=297272&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/misc-use-after-move.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/misc-use-after-move.cpp Wed Mar 8 06:34:51 2017 @@ -282,7 +282,7 @@ void moveInInitList() { S s{std::move(a)}; a.foo(); // CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'a' used after it was moved - // CHECK-MESSAGES: [[@LINE-3]]:6: note: move occurred here + // CHECK-MESSAGES: [[@LINE-3]]:7: note: move occurred here } void lambdas() { @@ -397,6 +397,21 @@ void movedTypeIsDependentType() { } template void movedTypeIsDependentType(); +// We handle the case correctly where the move consists of an implicit call +// to a conversion operator. +void implicitConversionOperator() { + struct Convertible { +operator A() && { return A(); } + }; + void takeA(A a); + + Convertible convertible; + takeA(std::move(convertible)); + convertible; + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'convertible' used after it was moved + // CHECK-MESSAGES: [[@LINE-3]]:9: note: move occurred here +} + // Using decltype on an expression is not a use. void decltypeIsNotUse() { A a; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30650: [clang-tidy] misc-use-after-move: Fix failing assertion
This revision was automatically updated to reflect the committed changes. Closed by commit rL297272: [clang-tidy] misc-use-after-move: Fix failing assertion (authored by mboehme). Changed prior to commit: https://reviews.llvm.org/D30650?vs=90692&id=90997#toc Repository: rL LLVM https://reviews.llvm.org/D30650 Files: clang-tools-extra/trunk/clang-tidy/misc/UseAfterMoveCheck.cpp clang-tools-extra/trunk/test/clang-tidy/misc-use-after-move.cpp Index: clang-tools-extra/trunk/clang-tidy/misc/UseAfterMoveCheck.cpp === --- clang-tools-extra/trunk/clang-tidy/misc/UseAfterMoveCheck.cpp +++ clang-tools-extra/trunk/clang-tidy/misc/UseAfterMoveCheck.cpp @@ -384,6 +384,13 @@ // the direct ancestor of the std::move() that isn't one of the node // types ignored by ignoringParenImpCasts(). stmt(forEach(expr(ignoringParenImpCasts(CallMoveMatcher))), + // Don't allow an InitListExpr to be the moving call. An InitListExpr + // has both a syntactic and a semantic form, and the parent-child + // relationships are different between the two. This could cause an + // InitListExpr to be analyzed as the moving call in addition to the + // Expr that we actually want, resulting in two diagnostics with + // different code locations for the same move. + unless(initListExpr()), unless(expr(ignoringParenImpCasts(equalsBoundNode("call-move") .bind("moving-call"), this); @@ -398,7 +405,7 @@ const auto *MovingCall = Result.Nodes.getNodeAs("moving-call"); const auto *Arg = Result.Nodes.getNodeAs("arg"); - if (!MovingCall) + if (!MovingCall || !MovingCall->getExprLoc().isValid()) MovingCall = CallMove; Stmt *FunctionBody = nullptr; Index: clang-tools-extra/trunk/test/clang-tidy/misc-use-after-move.cpp === --- clang-tools-extra/trunk/test/clang-tidy/misc-use-after-move.cpp +++ clang-tools-extra/trunk/test/clang-tidy/misc-use-after-move.cpp @@ -282,7 +282,7 @@ S s{std::move(a)}; a.foo(); // CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'a' used after it was moved - // CHECK-MESSAGES: [[@LINE-3]]:6: note: move occurred here + // CHECK-MESSAGES: [[@LINE-3]]:7: note: move occurred here } void lambdas() { @@ -397,6 +397,21 @@ } template void movedTypeIsDependentType(); +// We handle the case correctly where the move consists of an implicit call +// to a conversion operator. +void implicitConversionOperator() { + struct Convertible { +operator A() && { return A(); } + }; + void takeA(A a); + + Convertible convertible; + takeA(std::move(convertible)); + convertible; + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'convertible' used after it was moved + // CHECK-MESSAGES: [[@LINE-3]]:9: note: move occurred here +} + // Using decltype on an expression is not a use. void decltypeIsNotUse() { A a; Index: clang-tools-extra/trunk/clang-tidy/misc/UseAfterMoveCheck.cpp === --- clang-tools-extra/trunk/clang-tidy/misc/UseAfterMoveCheck.cpp +++ clang-tools-extra/trunk/clang-tidy/misc/UseAfterMoveCheck.cpp @@ -384,6 +384,13 @@ // the direct ancestor of the std::move() that isn't one of the node // types ignored by ignoringParenImpCasts(). stmt(forEach(expr(ignoringParenImpCasts(CallMoveMatcher))), + // Don't allow an InitListExpr to be the moving call. An InitListExpr + // has both a syntactic and a semantic form, and the parent-child + // relationships are different between the two. This could cause an + // InitListExpr to be analyzed as the moving call in addition to the + // Expr that we actually want, resulting in two diagnostics with + // different code locations for the same move. + unless(initListExpr()), unless(expr(ignoringParenImpCasts(equalsBoundNode("call-move") .bind("moving-call"), this); @@ -398,7 +405,7 @@ const auto *MovingCall = Result.Nodes.getNodeAs("moving-call"); const auto *Arg = Result.Nodes.getNodeAs("arg"); - if (!MovingCall) + if (!MovingCall || !MovingCall->getExprLoc().isValid()) MovingCall = CallMove; Stmt *FunctionBody = nullptr; Index: clang-tools-extra/trunk/test/clang-tidy/misc-use-after-move.cpp === --- clang-tools-extra/trunk/test/clang-tidy/misc-use-after-move.cpp +++ clang-tools-extra/trunk/test/clang-tidy/misc-use-after-move.cpp @@ -282,7 +282,7 @@ S s{std::move(a)}; a.foo(); // CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'a' used after it was moved - // CHECK-MESSAGES: [[@LINE-3]]:6: note: move occurred here + // CHECK-MESSAGES: [[@LINE-3]]:7: note: move occurred here } void lambdas() { @@ -397,6 +397,21 @@ } template void movedTy
[PATCH] D30575: [clang-format] Look at NoLineBreak and NoLineBreakInOperand before breakProtrudingToken
krasimir updated this revision to Diff 90999. krasimir added a comment. - Remove empty stack check https://reviews.llvm.org/D30575 Files: lib/Format/ContinuationIndenter.cpp unittests/Format/FormatTest.cpp Index: unittests/Format/FormatTest.cpp === --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -6471,8 +6471,9 @@ "_T(\"aa\")\n" "_T(\"\")", format(" _T(\"\")", Style)); - EXPECT_EQ("f(x, _T(\"a\")\n" -" _T(\"aa\"),\n" + EXPECT_EQ("f(x,\n" +" _T(\"\")\n" +" _T(\"aaa\"),\n" " z);", format("f(x, _T(\"aaa\"), z);", Style)); @@ -6504,6 +6505,90 @@ "_T(\"Xn\"));")); } +TEST_F(FormatTest, BreaksStringLiteralOperands) { + // In a function call with two operands, the second can be broken with no line + // break before it. + EXPECT_EQ("func(a, \"long long \"\n" +"\"long long\");", +format("func(a, \"long long long long\");", + getLLVMStyleWithColumns(24))); + // In a function call with three operands, the second must be broken with a + // line break before it. + EXPECT_EQ("func(a,\n" +" \"long long long \"\n" +" \"long\",\n" +" c);", +format("func(a, \"long long long long\", c);", + getLLVMStyleWithColumns(24))); + // In a function call with three operands, the third must be broken with a + // line break before it. + EXPECT_EQ("func(a, b,\n" +" \"long long long \"\n" +" \"long\");", +format("func(a, b, \"long long long long\");", + getLLVMStyleWithColumns(24))); + // In a function call with three operands, both the second and the third must + // be broken with a line break before them. + EXPECT_EQ("func(a,\n" +" \"long long long \"\n" +" \"long\",\n" +" \"long long long \"\n" +" \"long\");", +format("func(a, \"long long long long\", \"long long long long\");", + getLLVMStyleWithColumns(24))); + // In a chain of << with two operands, the second can be broken with no line + // break before it. + EXPECT_EQ("a << \"line line \"\n" +" \"line\";", +format("a << \"line line line\";", + getLLVMStyleWithColumns(20))); + // In a chain of << with three operands, the second can be broken with no line + // break before it. + EXPECT_EQ("abcde << \"line \"\n" +" \"line line\"\n" +" << c;", +format("abcde << \"line line line\" << c;", + getLLVMStyleWithColumns(20))); + // In a chain of << with three operands, the third must be broken with a line + // break before it. + EXPECT_EQ("a << b\n" +" << \"line line \"\n" +" \"line\";", +format("a << b << \"line line line\";", + getLLVMStyleWithColumns(20))); + // In a chain of << with three operands, the second can be broken with no line + // break before it and the third must be broken with a line break before it. + EXPECT_EQ("abcd << \"line line \"\n" +"\"line\"\n" +" << \"line line \"\n" +"\"line\";", +format("abcd << \"line line line\" << \"line line line\";", + getLLVMStyleWithColumns(20))); + // In a chain of binary operators with two operands, the second can be broken + // with no line break before it. + EXPECT_EQ("abcd + \"line line \"\n" +" \"line line\";", +format("abcd + \"line line line line\";", + getLLVMStyleWithColumns(20))); + // In a chain of binary operators with three operands, the second must be + // broken with a line break before it. + EXPECT_EQ("abcd +\n" +"\"line line \"\n" +"\"line line\" +\n" +"e;", +format("abcd + \"line line line line\" + e;", + getLLVMStyleWithColumns(20))); + // In a function call with two operands, with AlignAfterOpenBracket enabled, + // the first must be broken with a line break before it. + FormatStyle Style = getLLVMStyleWithColumns(25); + Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + EXPECT_EQ("someFunction(\n" +"\"long long long \"\n" +"\"long\",\n" +"a);", +format("someFunction(\"long long long long\", a);", Style)); +} + TEST_F(FormatTest, DontSplitStringLiteralsWithEscapedNewlines) { EXPECT_EQ( "aaa = \"aaa\\\n" Index: lib/Format/ContinuationIndenter.cpp ===
[PATCH] D30575: [clang-format] Look at NoLineBreak and NoLineBreakInOperand before breakProtrudingToken
djasper accepted this revision. djasper added a comment. This revision is now accepted and ready to land. Looks good. https://reviews.llvm.org/D30575 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30575: [clang-format] Look at NoLineBreak and NoLineBreakInOperand before breakProtrudingToken
This revision was automatically updated to reflect the committed changes. Closed by commit rL297274: [clang-format] Look at NoLineBreak and NoLineBreakInOperand before… (authored by krasimir). Changed prior to commit: https://reviews.llvm.org/D30575?vs=90999&id=91000#toc Repository: rL LLVM https://reviews.llvm.org/D30575 Files: cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/unittests/Format/FormatTest.cpp Index: cfe/trunk/lib/Format/ContinuationIndenter.cpp === --- cfe/trunk/lib/Format/ContinuationIndenter.cpp +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp @@ -848,6 +848,8 @@ (Current.IsMultiline ? Current.LastLineColumnWidth : State.Column + Current.ColumnWidth) - strlen("${"); + bool CanBreakProtrudingToken = !State.Stack.back().NoLineBreak && + !State.Stack.back().NoLineBreakInOperand; moveStatePastScopeOpener(State, Newline); moveStatePastFakeRParens(State); @@ -861,7 +863,9 @@ State.Column += Current.ColumnWidth; State.NextToken = State.NextToken->Next; - unsigned Penalty = breakProtrudingToken(Current, State, DryRun); + unsigned Penalty = 0; + if (CanBreakProtrudingToken) +Penalty = breakProtrudingToken(Current, State, DryRun); if (State.Column > getColumnLimit(State)) { unsigned ExcessCharacters = State.Column - getColumnLimit(State); Penalty += Style.PenaltyExcessCharacter * ExcessCharacters; Index: cfe/trunk/unittests/Format/FormatTest.cpp === --- cfe/trunk/unittests/Format/FormatTest.cpp +++ cfe/trunk/unittests/Format/FormatTest.cpp @@ -6471,8 +6471,9 @@ "_T(\"aa\")\n" "_T(\"\")", format(" _T(\"\")", Style)); - EXPECT_EQ("f(x, _T(\"a\")\n" -" _T(\"aa\"),\n" + EXPECT_EQ("f(x,\n" +" _T(\"\")\n" +" _T(\"aaa\"),\n" " z);", format("f(x, _T(\"aaa\"), z);", Style)); @@ -6504,6 +6505,90 @@ "_T(\"Xn\"));")); } +TEST_F(FormatTest, BreaksStringLiteralOperands) { + // In a function call with two operands, the second can be broken with no line + // break before it. + EXPECT_EQ("func(a, \"long long \"\n" +"\"long long\");", +format("func(a, \"long long long long\");", + getLLVMStyleWithColumns(24))); + // In a function call with three operands, the second must be broken with a + // line break before it. + EXPECT_EQ("func(a,\n" +" \"long long long \"\n" +" \"long\",\n" +" c);", +format("func(a, \"long long long long\", c);", + getLLVMStyleWithColumns(24))); + // In a function call with three operands, the third must be broken with a + // line break before it. + EXPECT_EQ("func(a, b,\n" +" \"long long long \"\n" +" \"long\");", +format("func(a, b, \"long long long long\");", + getLLVMStyleWithColumns(24))); + // In a function call with three operands, both the second and the third must + // be broken with a line break before them. + EXPECT_EQ("func(a,\n" +" \"long long long \"\n" +" \"long\",\n" +" \"long long long \"\n" +" \"long\");", +format("func(a, \"long long long long\", \"long long long long\");", + getLLVMStyleWithColumns(24))); + // In a chain of << with two operands, the second can be broken with no line + // break before it. + EXPECT_EQ("a << \"line line \"\n" +" \"line\";", +format("a << \"line line line\";", + getLLVMStyleWithColumns(20))); + // In a chain of << with three operands, the second can be broken with no line + // break before it. + EXPECT_EQ("abcde << \"line \"\n" +" \"line line\"\n" +" << c;", +format("abcde << \"line line line\" << c;", + getLLVMStyleWithColumns(20))); + // In a chain of << with three operands, the third must be broken with a line + // break before it. + EXPECT_EQ("a << b\n" +" << \"line line \"\n" +" \"line\";", +format("a << b << \"line line line\";", + getLLVMStyleWithColumns(20))); + // In a chain of << with three operands, the second can be broken with no line + // break before it and the third must be broken with a line break before it. + EXPECT_EQ("abcd << \"line line \"\n" +"\"line\"\n" +" << \"line line \"\n" +"\"line\";", +format("abcd << \"line line line\" << \"line line line\";", + getLLVMStyl
r297274 - [clang-format] Look at NoLineBreak and NoLineBreakInOperand before breakProtrudingToken
Author: krasimir Date: Wed Mar 8 06:54:50 2017 New Revision: 297274 URL: http://llvm.org/viewvc/llvm-project?rev=297274&view=rev Log: [clang-format] Look at NoLineBreak and NoLineBreakInOperand before breakProtrudingToken Summary: This patch makes ContinuationIndenter call breakProtrudingToken only if NoLineBreak and NoLineBreakInOperand is false. Previously, clang-format required two runs to converge on the following example with 24 columns: Note that the second operand shouldn't be splitted according to NoLineBreakInOperand, but the token breaker doesn't take that into account: ``` func(a, "long long long long", c); ``` After first run: ``` func(a, "long long " "long long", c); ``` After second run, where NoLineBreakInOperand is taken into account: ``` func(a, "long long " "long long", c); ``` With the patch, clang-format now obtains in one run: ``` func(a, "long long long" "long", c); ``` which is a better token split overall. Reviewers: djasper Reviewed By: djasper Subscribers: cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D30575 Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=297274&r1=297273&r2=297274&view=diff == --- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original) +++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Wed Mar 8 06:54:50 2017 @@ -848,6 +848,8 @@ unsigned ContinuationIndenter::moveState (Current.IsMultiline ? Current.LastLineColumnWidth : State.Column + Current.ColumnWidth) - strlen("${"); + bool CanBreakProtrudingToken = !State.Stack.back().NoLineBreak && + !State.Stack.back().NoLineBreakInOperand; moveStatePastScopeOpener(State, Newline); moveStatePastFakeRParens(State); @@ -861,7 +863,9 @@ unsigned ContinuationIndenter::moveState State.Column += Current.ColumnWidth; State.NextToken = State.NextToken->Next; - unsigned Penalty = breakProtrudingToken(Current, State, DryRun); + unsigned Penalty = 0; + if (CanBreakProtrudingToken) +Penalty = breakProtrudingToken(Current, State, DryRun); if (State.Column > getColumnLimit(State)) { unsigned ExcessCharacters = State.Column - getColumnLimit(State); Penalty += Style.PenaltyExcessCharacter * ExcessCharacters; Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=297274&r1=297273&r2=297274&view=diff == --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Wed Mar 8 06:54:50 2017 @@ -6471,8 +6471,9 @@ TEST_F(FormatTest, BreaksStringLiteralsW "_T(\"aa\")\n" "_T(\"\")", format(" _T(\"\")", Style)); - EXPECT_EQ("f(x, _T(\"a\")\n" -" _T(\"aa\"),\n" + EXPECT_EQ("f(x,\n" +" _T(\"\")\n" +" _T(\"aaa\"),\n" " z);", format("f(x, _T(\"aaa\"), z);", Style)); @@ -6504,6 +6505,90 @@ TEST_F(FormatTest, BreaksStringLiteralsW "_T(\"Xn\"));")); } +TEST_F(FormatTest, BreaksStringLiteralOperands) { + // In a function call with two operands, the second can be broken with no line + // break before it. + EXPECT_EQ("func(a, \"long long \"\n" +"\"long long\");", +format("func(a, \"long long long long\");", + getLLVMStyleWithColumns(24))); + // In a function call with three operands, the second must be broken with a + // line break before it. + EXPECT_EQ("func(a,\n" +" \"long long long \"\n" +" \"long\",\n" +" c);", +format("func(a, \"long long long long\", c);", + getLLVMStyleWithColumns(24))); + // In a function call with three operands, the third must be broken with a + // line break before it. + EXPECT_EQ("func(a, b,\n" +" \"long long long \"\n" +" \"long\");", +format("func(a, b, \"long long long long\");", + getLLVMStyleWithColumns(24))); + // In a function call with three operands, both the second and the third must + // be broken with a line break before them. + EXPECT_EQ("func(a,\n" +" \"long long long \"\n" +" \"long\",\n" +" \"long long long \"\n" +" \"long\");", +format("func(a, \"long long long long\", \"long long long long\");", + getLL
[PATCH] D30734: Add more examples to clang-format configuration
sylvestre.ledru created this revision. Herald added a subscriber: klimek. https://reviews.llvm.org/D30734 Files: docs/ClangFormatStyleOptions.rst include/clang/Format/Format.h Index: include/clang/Format/Format.h === --- include/clang/Format/Format.h +++ include/clang/Format/Format.h @@ -162,10 +162,27 @@ /// \brief Never merge functions into a single line. SFS_None, /// \brief Only merge empty functions. +/// \code +/// void f() { bar(); } +/// void f2() { +/// bar2(); +/// } +/// \endcode SFS_Empty, /// \brief Only merge functions defined inside a class. Implies "empty". +/// \code +/// class { +/// void f() { foo(); } +/// }; +/// \endcode SFS_Inline, /// \brief Merge all functions fitting on a single line. +/// \code +/// class { +/// void f() { foo(); } +/// }; +/// void f() { bar(); } +/// \endcode SFS_All, }; @@ -184,10 +201,42 @@ enum DefinitionReturnTypeBreakingStyle { /// Break after return type automatically. /// ``PenaltyReturnTypeOnItsOwnLine`` is taken into account. +/// \code +/// class A { +/// int f() { return 0; }; +/// }; +/// int f(); +/// int f() { +/// return 1; +/// } +/// \endcode DRTBS_None, /// Always break after the return type. +/// \code +/// class A { +/// int +/// f() { +/// return 0; +/// }; +/// }; +/// int f(); +/// int +/// f() { +/// return 1; +/// } +/// \endcode DRTBS_All, /// Always break after the return types of top-level functions. +/// \code +/// class A { +/// int f() { return 0; }; +/// }; +/// int f(); +/// int +/// f() { +/// return 1; +/// } +/// \endcode DRTBS_TopLevel, }; @@ -196,14 +245,69 @@ enum ReturnTypeBreakingStyle { /// Break after return type automatically. /// ``PenaltyReturnTypeOnItsOwnLine`` is taken into account. +/// \code +/// class A { +/// int f() { return 0; }; +/// }; +/// int f(); +/// int f() { return 1; } +/// \endcode RTBS_None, /// Always break after the return type. +/// \code +/// class A { +/// int +/// f() { +/// return 0; +/// }; +/// }; +/// int +/// f(); +/// int +/// f() { +/// return 1; +/// } +/// \endcode RTBS_All, /// Always break after the return types of top-level functions. +/// \code +/// class A { +/// int f() { return 0; }; +/// }; +/// int +/// f(); +/// int +/// f() { +/// return 1; +/// } +/// \endcode RTBS_TopLevel, /// Always break after the return type of function definitions. +/// \code +/// class A { +/// int +/// f() { +/// return 0; +/// }; +/// }; +/// int f(); +/// int +/// f() { +/// return 1; +/// } +/// \endcode RTBS_AllDefinitions, /// Always break after the return type of top-level definitions. +/// \code +/// class A { +/// int f() { return 0; }; +/// }; +/// int f(); +/// int +/// f() { +/// return 1; +/// } +/// \endcode RTBS_TopLevelDefinitions, }; @@ -589,10 +693,19 @@ /// \brief The ``&`` and ``*`` alignment style. enum PointerAlignmentStyle { /// Align pointer to the left. +/// \code +/// int* a; +/// \endcode PAS_Left, /// Align pointer to the right. +/// \code +/// int *a; +/// \endcode PAS_Right, /// Align pointer in the middle. +/// \code +/// int * a; +/// \endcode PAS_Middle }; @@ -603,9 +716,18 @@ bool ReflowComments; /// \brief If ``true``, clang-format will sort ``#includes``. + /// \code + ///false: true: + ///#include "b.h" vs. #include "a.h" + ///#include "a.h" #include "b.h" + /// \endcode bool SortIncludes; /// \brief If ``true``, a space may be inserted after C style casts. + /// \code + ///true: false: + ///(int)i;vs. (int) i; + /// \endcode bool SpaceAfterCStyleCast; /// \brief If \c true, a space will be inserted after the 'template' keyword. Index: docs/ClangFormatStyleOptions.rst === --- docs/ClangFormatStyleOptions.rst +++ docs/ClangFormatStyleOptions.rst @@ -283,14 +283,34 @@ * ``SFS_Empty`` (in configuration: ``Empty``) Only merge empty functions. +.. code-block:: c++ + +
[PATCH] D30734: Add more examples to clang-format configuration
djasper accepted this revision. djasper added a comment. This revision is now accepted and ready to land. Please upload patches with full context or use arc (https://secure.phabricator.com/book/phabricator/article/arcanist/). Generally looks good, just minor comments. Comment at: include/clang/Format/Format.h:201 enum DefinitionReturnTypeBreakingStyle { /// Break after return type automatically. Don't add examples here as this is deprecated. Maybe make it more obvious that this is deprecated instead. Comment at: include/clang/Format/Format.h:726 /// \brief If ``true``, a space may be inserted after C style casts. + /// \code While you are here: s/may be/is/ https://reviews.llvm.org/D30734 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30734: Add more examples to clang-format configuration
sylvestre.ledru updated this revision to Diff 91002. sylvestre.ledru added a comment. with the changes, I will land it now https://reviews.llvm.org/D30734 Files: docs/ClangFormatStyleOptions.rst include/clang/Format/Format.h Index: include/clang/Format/Format.h === --- include/clang/Format/Format.h +++ include/clang/Format/Format.h @@ -162,10 +162,27 @@ /// \brief Never merge functions into a single line. SFS_None, /// \brief Only merge empty functions. +/// \code +/// void f() { bar(); } +/// void f2() { +/// bar2(); +/// } +/// \endcode SFS_Empty, /// \brief Only merge functions defined inside a class. Implies "empty". +/// \code +/// class { +/// void f() { foo(); } +/// }; +/// \endcode SFS_Inline, /// \brief Merge all functions fitting on a single line. +/// \code +/// class { +/// void f() { foo(); } +/// }; +/// void f() { bar(); } +/// \endcode SFS_All, }; @@ -181,6 +198,7 @@ bool AllowShortLoopsOnASingleLine; /// \brief Different ways to break after the function definition return type. + /// This option is deprecated and is retained for backwards compatibility. enum DefinitionReturnTypeBreakingStyle { /// Break after return type automatically. /// ``PenaltyReturnTypeOnItsOwnLine`` is taken into account. @@ -196,14 +214,69 @@ enum ReturnTypeBreakingStyle { /// Break after return type automatically. /// ``PenaltyReturnTypeOnItsOwnLine`` is taken into account. +/// \code +/// class A { +/// int f() { return 0; }; +/// }; +/// int f(); +/// int f() { return 1; } +/// \endcode RTBS_None, /// Always break after the return type. +/// \code +/// class A { +/// int +/// f() { +/// return 0; +/// }; +/// }; +/// int +/// f(); +/// int +/// f() { +/// return 1; +/// } +/// \endcode RTBS_All, /// Always break after the return types of top-level functions. +/// \code +/// class A { +/// int f() { return 0; }; +/// }; +/// int +/// f(); +/// int +/// f() { +/// return 1; +/// } +/// \endcode RTBS_TopLevel, /// Always break after the return type of function definitions. +/// \code +/// class A { +/// int +/// f() { +/// return 0; +/// }; +/// }; +/// int f(); +/// int +/// f() { +/// return 1; +/// } +/// \endcode RTBS_AllDefinitions, /// Always break after the return type of top-level definitions. +/// \code +/// class A { +/// int f() { return 0; }; +/// }; +/// int f(); +/// int +/// f() { +/// return 1; +/// } +/// \endcode RTBS_TopLevelDefinitions, }; @@ -589,10 +662,19 @@ /// \brief The ``&`` and ``*`` alignment style. enum PointerAlignmentStyle { /// Align pointer to the left. +/// \code +/// int* a; +/// \endcode PAS_Left, /// Align pointer to the right. +/// \code +/// int *a; +/// \endcode PAS_Right, /// Align pointer in the middle. +/// \code +/// int * a; +/// \endcode PAS_Middle }; @@ -603,9 +685,18 @@ bool ReflowComments; /// \brief If ``true``, clang-format will sort ``#includes``. + /// \code + ///false: true: + ///#include "b.h" vs. #include "a.h" + ///#include "a.h" #include "b.h" + /// \endcode bool SortIncludes; - /// \brief If ``true``, a space may be inserted after C style casts. + /// \brief If ``true``, a space is inserted after C style casts. + /// \code + ///true: false: + ///(int)i;vs. (int) i; + /// \endcode bool SpaceAfterCStyleCast; /// \brief If \c true, a space will be inserted after the 'template' keyword. Index: docs/ClangFormatStyleOptions.rst === --- docs/ClangFormatStyleOptions.rst +++ docs/ClangFormatStyleOptions.rst @@ -283,14 +283,34 @@ * ``SFS_Empty`` (in configuration: ``Empty``) Only merge empty functions. +.. code-block:: c++ + + void f() { bar(); } + void f2() { +bar2(); + } + * ``SFS_Inline`` (in configuration: ``Inline``) Only merge functions defined inside a class. Implies "empty". +.. code-block:: c++ + + class { +void f() { foo(); } + }; + * ``SFS_All`` (in configuration: ``All``) Merge all functions fitting on a single line. +.. code-block:: c++ + class { +void f() { foo(); } + }; + void f() { ba
r297275 - Add more examples to clang-format configuration
Author: sylvestre Date: Wed Mar 8 07:24:46 2017 New Revision: 297275 URL: http://llvm.org/viewvc/llvm-project?rev=297275&view=rev Log: Add more examples to clang-format configuration Reviewers: djasper Reviewed By: djasper Subscribers: cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D30734 Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst cfe/trunk/include/clang/Format/Format.h Modified: cfe/trunk/docs/ClangFormatStyleOptions.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangFormatStyleOptions.rst?rev=297275&r1=297274&r2=297275&view=diff == --- cfe/trunk/docs/ClangFormatStyleOptions.rst (original) +++ cfe/trunk/docs/ClangFormatStyleOptions.rst Wed Mar 8 07:24:46 2017 @@ -283,12 +283,32 @@ the configuration (without a prefix: ``A * ``SFS_Empty`` (in configuration: ``Empty``) Only merge empty functions. +.. code-block:: c++ + + void f() { bar(); } + void f2() { +bar2(); + } + * ``SFS_Inline`` (in configuration: ``Inline``) Only merge functions defined inside a class. Implies "empty". +.. code-block:: c++ + + class { +void f() { foo(); } + }; + * ``SFS_All`` (in configuration: ``All``) Merge all functions fitting on a single line. +.. code-block:: c++ + + class { +void f() { foo(); } + }; + void f() { bar(); } + **AllowShortIfStatementsOnASingleLine** (``bool``) @@ -325,18 +345,78 @@ the configuration (without a prefix: ``A Break after return type automatically. ``PenaltyReturnTypeOnItsOwnLine`` is taken into account. +.. code-block:: c++ + + class A { +int f() { return 0; }; + }; + int f(); + int f() { return 1; } + * ``RTBS_All`` (in configuration: ``All``) Always break after the return type. +.. code-block:: c++ + + class A { +int +f() { + return 0; +}; + }; + int + f(); + int + f() { +return 1; + } + * ``RTBS_TopLevel`` (in configuration: ``TopLevel``) Always break after the return types of top-level functions. +.. code-block:: c++ + + class A { +int f() { return 0; }; + }; + int + f(); + int + f() { +return 1; + } + * ``RTBS_AllDefinitions`` (in configuration: ``AllDefinitions``) Always break after the return type of function definitions. +.. code-block:: c++ + + class A { +int +f() { + return 0; +}; + }; + int f(); + int + f() { +return 1; + } + * ``RTBS_TopLevelDefinitions`` (in configuration: ``TopLevelDefinitions``) Always break after the return type of top-level definitions. +.. code-block:: c++ + + class A { +int f() { return 0; }; + }; + int f(); + int + f() { +return 1; + } + **AlwaysBreakBeforeMultilineStrings** (``bool``) @@ -722,12 +802,24 @@ the configuration (without a prefix: ``A * ``PAS_Left`` (in configuration: ``Left``) Align pointer to the left. +.. code-block:: c++ + + int\* a; + * ``PAS_Right`` (in configuration: ``Right``) Align pointer to the right. +.. code-block:: c++ + + int \*a; + * ``PAS_Middle`` (in configuration: ``Middle``) Align pointer in the middle. +.. code-block:: c++ + + int \* a; + **ReflowComments** (``bool``) @@ -736,8 +828,19 @@ the configuration (without a prefix: ``A **SortIncludes** (``bool``) If ``true``, clang-format will sort ``#includes``. + .. code-block:: c++ + + false: true: + #include "b.h" vs. #include "a.h" + #include "a.h" #include "b.h" + **SpaceAfterCStyleCast** (``bool``) - If ``true``, a space may be inserted after C style casts. + If ``true``, a space is inserted after C style casts. + + .. code-block:: c++ + + true: false: + (int)i;vs. (int) i; **SpaceAfterTemplateKeyword** (``bool``) If ``true``, a space will be inserted after the 'template' keyword. Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=297275&r1=297274&r2=297275&view=diff == --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Wed Mar 8 07:24:46 2017 @@ -162,10 +162,27 @@ struct FormatStyle { /// \brief Never merge functions into a single line. SFS_None, /// \brief Only merge empty functions. +/// \code +/// void f() { bar(); } +/// void f2() { +/// bar2(); +/// } +/// \endcode SFS_Empty, /// \brief Only
[PATCH] D30734: Add more examples to clang-format configuration
This revision was automatically updated to reflect the committed changes. Closed by commit rL297275: Add more examples to clang-format configuration (authored by sylvestre). Changed prior to commit: https://reviews.llvm.org/D30734?vs=91002&id=91003#toc Repository: rL LLVM https://reviews.llvm.org/D30734 Files: cfe/trunk/docs/ClangFormatStyleOptions.rst cfe/trunk/include/clang/Format/Format.h Index: cfe/trunk/docs/ClangFormatStyleOptions.rst === --- cfe/trunk/docs/ClangFormatStyleOptions.rst +++ cfe/trunk/docs/ClangFormatStyleOptions.rst @@ -283,12 +283,32 @@ * ``SFS_Empty`` (in configuration: ``Empty``) Only merge empty functions. +.. code-block:: c++ + + void f() { bar(); } + void f2() { +bar2(); + } + * ``SFS_Inline`` (in configuration: ``Inline``) Only merge functions defined inside a class. Implies "empty". +.. code-block:: c++ + + class { +void f() { foo(); } + }; + * ``SFS_All`` (in configuration: ``All``) Merge all functions fitting on a single line. +.. code-block:: c++ + + class { +void f() { foo(); } + }; + void f() { bar(); } + **AllowShortIfStatementsOnASingleLine** (``bool``) @@ -325,18 +345,78 @@ Break after return type automatically. ``PenaltyReturnTypeOnItsOwnLine`` is taken into account. +.. code-block:: c++ + + class A { +int f() { return 0; }; + }; + int f(); + int f() { return 1; } + * ``RTBS_All`` (in configuration: ``All``) Always break after the return type. +.. code-block:: c++ + + class A { +int +f() { + return 0; +}; + }; + int + f(); + int + f() { +return 1; + } + * ``RTBS_TopLevel`` (in configuration: ``TopLevel``) Always break after the return types of top-level functions. +.. code-block:: c++ + + class A { +int f() { return 0; }; + }; + int + f(); + int + f() { +return 1; + } + * ``RTBS_AllDefinitions`` (in configuration: ``AllDefinitions``) Always break after the return type of function definitions. +.. code-block:: c++ + + class A { +int +f() { + return 0; +}; + }; + int f(); + int + f() { +return 1; + } + * ``RTBS_TopLevelDefinitions`` (in configuration: ``TopLevelDefinitions``) Always break after the return type of top-level definitions. +.. code-block:: c++ + + class A { +int f() { return 0; }; + }; + int f(); + int + f() { +return 1; + } + **AlwaysBreakBeforeMultilineStrings** (``bool``) @@ -722,22 +802,45 @@ * ``PAS_Left`` (in configuration: ``Left``) Align pointer to the left. +.. code-block:: c++ + + int\* a; + * ``PAS_Right`` (in configuration: ``Right``) Align pointer to the right. +.. code-block:: c++ + + int \*a; + * ``PAS_Middle`` (in configuration: ``Middle``) Align pointer in the middle. +.. code-block:: c++ + + int \* a; + **ReflowComments** (``bool``) If ``true``, clang-format will attempt to re-flow comments. **SortIncludes** (``bool``) If ``true``, clang-format will sort ``#includes``. + .. code-block:: c++ + + false: true: + #include "b.h" vs. #include "a.h" + #include "a.h" #include "b.h" + **SpaceAfterCStyleCast** (``bool``) - If ``true``, a space may be inserted after C style casts. + If ``true``, a space is inserted after C style casts. + + .. code-block:: c++ + + true: false: + (int)i;vs. (int) i; **SpaceAfterTemplateKeyword** (``bool``) If ``true``, a space will be inserted after the 'template' keyword. Index: cfe/trunk/include/clang/Format/Format.h === --- cfe/trunk/include/clang/Format/Format.h +++ cfe/trunk/include/clang/Format/Format.h @@ -162,10 +162,27 @@ /// \brief Never merge functions into a single line. SFS_None, /// \brief Only merge empty functions. +/// \code +/// void f() { bar(); } +/// void f2() { +/// bar2(); +/// } +/// \endcode SFS_Empty, /// \brief Only merge functions defined inside a class. Implies "empty". +/// \code +/// class { +/// void f() { foo(); } +/// }; +/// \endcode SFS_Inline, /// \brief Merge all functions fitting on a single line. +/// \code +/// class { +/// void f() { foo(); } +/// }; +/// void f() { bar(); } +/// \endcode SFS_All, }; @@ -181,6 +198,7 @@ bool AllowShortLoopsOnASingleLine; /// \brief Different ways to break after the functio
[PATCH] D28820: Warn when calling a non interrupt function from an interrupt on ARM
jroelofs added a comment. In https://reviews.llvm.org/D28820#695356, @tyomitch wrote: > When compiling for softfp targets, this new warning doesn't make sense: there > are no VFP registers to save. > Jonathan, would you please conditionalize it to only affect hardfp targets? Sure, I can do that. https://reviews.llvm.org/D28820 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30166: Honor __unaligned in codegen for declarations and expressions
This revision was automatically updated to reflect the committed changes. Closed by commit rL297276: Honor __unaligned in codegen for declarations and expressions (authored by rogfer01). Changed prior to commit: https://reviews.llvm.org/D30166?vs=89989&id=91005#toc Repository: rL LLVM https://reviews.llvm.org/D30166 Files: cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.cpp cfe/trunk/test/CodeGen/unaligned-decl.c cfe/trunk/test/CodeGen/unaligned-expr.c cfe/trunk/test/CodeGen/unaligned-field.c cfe/trunk/test/CodeGenCXX/unaligned.cpp Index: cfe/trunk/test/CodeGenCXX/unaligned.cpp === --- cfe/trunk/test/CodeGenCXX/unaligned.cpp +++ cfe/trunk/test/CodeGenCXX/unaligned.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -x c++ -std=c++11 -triple x86_64-unknown-linux-gnu -fms-extensions -emit-llvm < %s | FileCheck %s + +int foo() { + // CHECK: ret i32 1 + return alignof(__unaligned int); +} Index: cfe/trunk/test/CodeGen/unaligned-expr.c === --- cfe/trunk/test/CodeGen/unaligned-expr.c +++ cfe/trunk/test/CodeGen/unaligned-expr.c @@ -0,0 +1,217 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fms-extensions -emit-llvm < %s | FileCheck %s + +// - +// Scalar integer +// - +__unaligned int x; +void test1(void) { + // CHECK: {{%.*}} = load i32, i32* @x, align 1 + // CHECK: store i32 {{%.*}}, i32* @x, align 1 + x++; +} + +void test2(void) { + // CHECK: %y = alloca i32, align 1 + // CHECK: {{%.*}} = load i32, i32* %y, align 1 + // CHECK: store i32 {{%.*}}, i32* %y, align 1 + __unaligned int y; + y++; +} + +void test2_1(void) { + // CHECK: %y = alloca i32, align 1 + // CHECK: store i32 1, i32* %y, align 1 + __unaligned int y = 1; +} + +// - +// Global pointer +// - +int *__unaligned p1; +void test3(void) { + + // CHECK: {{%.*}} = load i32*, i32** @p1, align 1 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 4 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 4 + (*p1)++; +} + +int __unaligned *p2; +void test4(void) { + // CHECK: {{%.*}} = load i32*, i32** @p2, align 8 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1 + (*p2)++; +} + +int __unaligned *__unaligned p3; +void test5(void) { + // CHECK: {{%.*}} = load i32*, i32** @p3, align 1 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1 + (*p3)++; +} + +// - +// Local pointer +// - +void test6(void) { + // CHECK: %lp1 = alloca i32*, align 1 + // CHECK: {{%.*}} = load i32*, i32** %lp1, align 1 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 4 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 4 + int *__unaligned lp1; + (*lp1)++; +} + +void test7(void) { + // CHECK: %lp2 = alloca i32*, align 8 + // CHECK: {{%.*}} = load i32*, i32** %lp2, align 8 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1 + int __unaligned *lp2; + (*lp2)++; +} + +void test8(void) { + // CHECK: %lp3 = alloca i32*, align 1 + // CHECK: {{%.*}} = load i32*, i32** %lp3, align 1 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1 + int __unaligned *__unaligned lp3; + (*lp3)++; +} + +// - +// Global array +// - +__unaligned int a[10]; +void test9(void) { + // CHECK: {{%.*}} = load i32, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @a, i64 0, i64 3), align 1 + // CHECK: store i32 {{%.*}}, i32* getelementptr inbounds ([10 x i32], [10 x i32]* @a, i64 0, i64 3), align 1 + (a[3])++; +} + +// - +// Local array +// - +void test10(void) { + // CHECK: %la = alloca [10 x i32], align 1 + // CHECK: {{%.*}} = getelementptr inbounds [10 x i32], [10 x i32]* %la, i64 0, i64 3 + // CHECK: {{%.*}} = load i32, i32* {{%.*}}, align 1 + // CHECK: store i32 {{%.*}}, i32* {{%.*}}, align 1 + __unaligned int la[10]; + (la[3])++; +} + +// +// Typedefs +// + +typedef __unaligned int UnalignedInt; +void test13() { + // CHECK: %i = alloca i32, align 1 + // CHECK: {{%.*}} = load i32, i32* %i, align 1 + // CHECK: store i32 {{%.*}}, i32* %i, align 1 + UnalignedInt i; + i++; +} + +typedef int Aligned; +typedef __unaligned Aligned UnalignedInt2; +void test14() { + // CHECK: %i = alloca i32, align 1 + // CHECK: {{%.*}} = load i32, i32* %i, align 1 + // CHECK: store i32 {{%.*}}, i32* %i, align 1 + UnalignedInt2 i; + i++; +} + +typedef UnalignedInt UnalignedInt3; +void test15() { + // CHECK: %i = alloca i32, align 1 + // CHECK: {{%.*}} = load i32, i32* %i, align 1 + // CHECK: store i32 {{%.*}}, i32* %i, align 1 + UnalignedInt3 i; + i++; +} + +// - +// Decayed types +// - +void test1
r297276 - Honor __unaligned in codegen for declarations and expressions
Author: rogfer01 Date: Wed Mar 8 08:00:44 2017 New Revision: 297276 URL: http://llvm.org/viewvc/llvm-project?rev=297276&view=rev Log: Honor __unaligned in codegen for declarations and expressions This patch honors the unaligned type qualifier (currently available through he keyword __unaligned and -fms-extensions) in CodeGen. In the current form the patch affects declarations and expressions. It does not affect fields of classes. Differential Revision: https://reviews.llvm.org/D30166 Added: cfe/trunk/test/CodeGen/unaligned-decl.c cfe/trunk/test/CodeGen/unaligned-expr.c cfe/trunk/test/CodeGen/unaligned-field.c cfe/trunk/test/CodeGenCXX/unaligned.cpp Modified: cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Modified: cfe/trunk/lib/AST/ASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=297276&r1=297275&r2=297276&view=diff == --- cfe/trunk/lib/AST/ASTContext.cpp (original) +++ cfe/trunk/lib/AST/ASTContext.cpp Wed Mar 8 08:00:44 2017 @@ -1473,6 +1473,8 @@ CharUnits ASTContext::getDeclAlign(const } } Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr())); + if (BaseT.getQualifiers().hasUnaligned()) +Align = Target->getCharWidth(); if (const VarDecl *VD = dyn_cast(D)) { if (VD->hasGlobalStorage() && !ForAlignof) Align = std::max(Align, getTargetInfo().getMinGlobalAlign()); Modified: cfe/trunk/lib/AST/ExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=297276&r1=297275&r2=297276&view=diff == --- cfe/trunk/lib/AST/ExprConstant.cpp (original) +++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Mar 8 08:00:44 2017 @@ -5677,6 +5677,8 @@ static CharUnits GetAlignOfType(EvalInfo T = Ref->getPointeeType(); // __alignof is defined to return the preferred alignment. + if (T.getQualifiers().hasUnaligned()) +return CharUnits::One(); return Info.Ctx.toCharUnitsFromBits( Info.Ctx.getPreferredTypeAlign(T.getTypePtr())); } Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=297276&r1=297275&r2=297276&view=diff == --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original) +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Mar 8 08:00:44 2017 @@ -149,6 +149,8 @@ CharUnits CodeGenFunction::getNaturalTyp Alignment = CGM.getClassPointerAlignment(RD); } else { Alignment = getContext().getTypeAlignInChars(T); + if (T.getQualifiers().hasUnaligned()) +Alignment = CharUnits::One(); } // Cap to the global maximum type alignment unless the alignment Added: cfe/trunk/test/CodeGen/unaligned-decl.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/unaligned-decl.c?rev=297276&view=auto == --- cfe/trunk/test/CodeGen/unaligned-decl.c (added) +++ cfe/trunk/test/CodeGen/unaligned-decl.c Wed Mar 8 08:00:44 2017 @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fms-extensions -emit-llvm < %s | FileCheck %s + +// CHECK: @a1 = global i32 1, align 1 +__unaligned int a1 = 1; + +// CHECK: @a2 = global i32 1, align 1 +int __unaligned a2 = 1; + +// CHECK: @a3 = {{.*}} align 1 +__unaligned int a3[10]; + +// CHECK: @a4 = {{.*}} align 1 +int __unaligned a4[10]; + +// CHECK: @p1 = {{.*}} align 1 +int *__unaligned p1; + +// CHECK: @p2 = {{.*}} align 8 +int __unaligned *p2; + +// CHECK: @p3 = {{.*}} align 1 +int __unaligned *__unaligned p3; Added: cfe/trunk/test/CodeGen/unaligned-expr.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/unaligned-expr.c?rev=297276&view=auto == --- cfe/trunk/test/CodeGen/unaligned-expr.c (added) +++ cfe/trunk/test/CodeGen/unaligned-expr.c Wed Mar 8 08:00:44 2017 @@ -0,0 +1,217 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fms-extensions -emit-llvm < %s | FileCheck %s + +// - +// Scalar integer +// - +__unaligned int x; +void test1(void) { + // CHECK: {{%.*}} = load i32, i32* @x, align 1 + // CHECK: store i32 {{%.*}}, i32* @x, align 1 + x++; +} + +void test2(void) { + // CHECK: %y = alloca i32, align 1 + // CHECK: {{%.*}} = load i32, i32* %y, align 1 + // CHECK: store i32 {{%.*}}, i32* %y, align 1 + __unaligned int y; + y++; +} + +void test2_1(void) { + // CHECK: %y = alloca i32, align 1 + // CHECK: store i32 1, i32* %y, align 1 + __unaligned int y = 1; +} + +// - +// Global pointer +// - +int *__unaligned p1; +void test3(void) { + + //
[PATCH] D30735: Add missing implementation for AtomicChange::replace(...)
ioeric created this revision. Just realized the implementation is missing... https://reviews.llvm.org/D30735 Files: lib/Tooling/Refactoring/AtomicChange.cpp unittests/Tooling/RefactoringTest.cpp Index: unittests/Tooling/RefactoringTest.cpp === --- unittests/Tooling/RefactoringTest.cpp +++ unittests/Tooling/RefactoringTest.cpp @@ -1173,8 +1173,10 @@ EXPECT_EQ(ExpectedChange.getKey(), ActualChange.getKey()); EXPECT_EQ(ExpectedChange.getFilePath(), ActualChange.getFilePath()); EXPECT_EQ(ExpectedChange.getError(), ActualChange.getError()); - EXPECT_EQ(ExpectedChange.getInsertedHeaders(), ActualChange.getInsertedHeaders()); - EXPECT_EQ(ExpectedChange.getRemovedHeaders(), ActualChange.getRemovedHeaders()); + EXPECT_EQ(ExpectedChange.getInsertedHeaders(), +ActualChange.getInsertedHeaders()); + EXPECT_EQ(ExpectedChange.getRemovedHeaders(), +ActualChange.getRemovedHeaders()); EXPECT_EQ(ExpectedChange.getReplacements().size(), ActualChange.getReplacements().size()); EXPECT_EQ(2u, ActualChange.getReplacements().size()); @@ -1191,6 +1193,22 @@ EXPECT_EQ("input.cpp", Change.getFilePath()); } +TEST_F(AtomicChangeTest, Replace) { + setUp(); + AtomicChange Change(Context.Sources, DefaultLoc); + llvm::Error Err = Change.replace(Context.Sources, DefaultLoc, 2, "aa"); + ASSERT_TRUE(!Err); + EXPECT_EQ(Change.getReplacements().size(), 1u); + EXPECT_EQ(*Change.getReplacements().begin(), +Replacement(Context.Sources, DefaultLoc, 2, "aa")); + + // Add a new replacement that conflicts with the existing one. + Err = Change.replace(Context.Sources, DefaultLoc, 3, "ab"); + EXPECT_TRUE((bool)Err); + llvm::consumeError(std::move(Err)); + EXPECT_EQ(Change.getReplacements().size(), 1u); +} + TEST_F(AtomicChangeTest, InsertBefore) { setUp(); AtomicChange Change(Context.Sources, DefaultLoc); Index: lib/Tooling/Refactoring/AtomicChange.cpp === --- lib/Tooling/Refactoring/AtomicChange.cpp +++ lib/Tooling/Refactoring/AtomicChange.cpp @@ -132,6 +132,12 @@ return E; } +llvm::Error AtomicChange::replace(const SourceManager &SM, SourceLocation Loc, + unsigned Length, llvm::StringRef Text) { + Replacement R(SM, Loc, Length, Text); + return Replaces.add(R); +} + llvm::Error AtomicChange::insert(const SourceManager &SM, SourceLocation Loc, llvm::StringRef Text, bool InsertAfter) { if (Text.empty()) Index: unittests/Tooling/RefactoringTest.cpp === --- unittests/Tooling/RefactoringTest.cpp +++ unittests/Tooling/RefactoringTest.cpp @@ -1173,8 +1173,10 @@ EXPECT_EQ(ExpectedChange.getKey(), ActualChange.getKey()); EXPECT_EQ(ExpectedChange.getFilePath(), ActualChange.getFilePath()); EXPECT_EQ(ExpectedChange.getError(), ActualChange.getError()); - EXPECT_EQ(ExpectedChange.getInsertedHeaders(), ActualChange.getInsertedHeaders()); - EXPECT_EQ(ExpectedChange.getRemovedHeaders(), ActualChange.getRemovedHeaders()); + EXPECT_EQ(ExpectedChange.getInsertedHeaders(), +ActualChange.getInsertedHeaders()); + EXPECT_EQ(ExpectedChange.getRemovedHeaders(), +ActualChange.getRemovedHeaders()); EXPECT_EQ(ExpectedChange.getReplacements().size(), ActualChange.getReplacements().size()); EXPECT_EQ(2u, ActualChange.getReplacements().size()); @@ -1191,6 +1193,22 @@ EXPECT_EQ("input.cpp", Change.getFilePath()); } +TEST_F(AtomicChangeTest, Replace) { + setUp(); + AtomicChange Change(Context.Sources, DefaultLoc); + llvm::Error Err = Change.replace(Context.Sources, DefaultLoc, 2, "aa"); + ASSERT_TRUE(!Err); + EXPECT_EQ(Change.getReplacements().size(), 1u); + EXPECT_EQ(*Change.getReplacements().begin(), +Replacement(Context.Sources, DefaultLoc, 2, "aa")); + + // Add a new replacement that conflicts with the existing one. + Err = Change.replace(Context.Sources, DefaultLoc, 3, "ab"); + EXPECT_TRUE((bool)Err); + llvm::consumeError(std::move(Err)); + EXPECT_EQ(Change.getReplacements().size(), 1u); +} + TEST_F(AtomicChangeTest, InsertBefore) { setUp(); AtomicChange Change(Context.Sources, DefaultLoc); Index: lib/Tooling/Refactoring/AtomicChange.cpp === --- lib/Tooling/Refactoring/AtomicChange.cpp +++ lib/Tooling/Refactoring/AtomicChange.cpp @@ -132,6 +132,12 @@ return E; } +llvm::Error AtomicChange::replace(const SourceManager &SM, SourceLocation Loc, + unsigned Length, llvm::StringRef Text) { + Replacement R(SM, Loc, Length, Text); + return Replaces.add(R); +} + llvm::Error AtomicChange::insert(const SourceManager &SM, SourceLocation Loc, llvm::StringRef Text, bool InsertAfter) { if (Text
[PATCH] D30735: Add missing implementation for AtomicChange::replace(...)
ioeric updated this revision to Diff 91010. ioeric added a comment. - Removed unnecessary variable. https://reviews.llvm.org/D30735 Files: lib/Tooling/Refactoring/AtomicChange.cpp unittests/Tooling/RefactoringTest.cpp Index: unittests/Tooling/RefactoringTest.cpp === --- unittests/Tooling/RefactoringTest.cpp +++ unittests/Tooling/RefactoringTest.cpp @@ -1173,8 +1173,10 @@ EXPECT_EQ(ExpectedChange.getKey(), ActualChange.getKey()); EXPECT_EQ(ExpectedChange.getFilePath(), ActualChange.getFilePath()); EXPECT_EQ(ExpectedChange.getError(), ActualChange.getError()); - EXPECT_EQ(ExpectedChange.getInsertedHeaders(), ActualChange.getInsertedHeaders()); - EXPECT_EQ(ExpectedChange.getRemovedHeaders(), ActualChange.getRemovedHeaders()); + EXPECT_EQ(ExpectedChange.getInsertedHeaders(), +ActualChange.getInsertedHeaders()); + EXPECT_EQ(ExpectedChange.getRemovedHeaders(), +ActualChange.getRemovedHeaders()); EXPECT_EQ(ExpectedChange.getReplacements().size(), ActualChange.getReplacements().size()); EXPECT_EQ(2u, ActualChange.getReplacements().size()); @@ -1191,6 +1193,22 @@ EXPECT_EQ("input.cpp", Change.getFilePath()); } +TEST_F(AtomicChangeTest, Replace) { + setUp(); + AtomicChange Change(Context.Sources, DefaultLoc); + llvm::Error Err = Change.replace(Context.Sources, DefaultLoc, 2, "aa"); + ASSERT_TRUE(!Err); + EXPECT_EQ(Change.getReplacements().size(), 1u); + EXPECT_EQ(*Change.getReplacements().begin(), +Replacement(Context.Sources, DefaultLoc, 2, "aa")); + + // Add a new replacement that conflicts with the existing one. + Err = Change.replace(Context.Sources, DefaultLoc, 3, "ab"); + EXPECT_TRUE((bool)Err); + llvm::consumeError(std::move(Err)); + EXPECT_EQ(Change.getReplacements().size(), 1u); +} + TEST_F(AtomicChangeTest, InsertBefore) { setUp(); AtomicChange Change(Context.Sources, DefaultLoc); Index: lib/Tooling/Refactoring/AtomicChange.cpp === --- lib/Tooling/Refactoring/AtomicChange.cpp +++ lib/Tooling/Refactoring/AtomicChange.cpp @@ -132,6 +132,11 @@ return E; } +llvm::Error AtomicChange::replace(const SourceManager &SM, SourceLocation Loc, + unsigned Length, llvm::StringRef Text) { + return Replaces.add(Replacement(SM, Loc, Length, Text)); +} + llvm::Error AtomicChange::insert(const SourceManager &SM, SourceLocation Loc, llvm::StringRef Text, bool InsertAfter) { if (Text.empty()) Index: unittests/Tooling/RefactoringTest.cpp === --- unittests/Tooling/RefactoringTest.cpp +++ unittests/Tooling/RefactoringTest.cpp @@ -1173,8 +1173,10 @@ EXPECT_EQ(ExpectedChange.getKey(), ActualChange.getKey()); EXPECT_EQ(ExpectedChange.getFilePath(), ActualChange.getFilePath()); EXPECT_EQ(ExpectedChange.getError(), ActualChange.getError()); - EXPECT_EQ(ExpectedChange.getInsertedHeaders(), ActualChange.getInsertedHeaders()); - EXPECT_EQ(ExpectedChange.getRemovedHeaders(), ActualChange.getRemovedHeaders()); + EXPECT_EQ(ExpectedChange.getInsertedHeaders(), +ActualChange.getInsertedHeaders()); + EXPECT_EQ(ExpectedChange.getRemovedHeaders(), +ActualChange.getRemovedHeaders()); EXPECT_EQ(ExpectedChange.getReplacements().size(), ActualChange.getReplacements().size()); EXPECT_EQ(2u, ActualChange.getReplacements().size()); @@ -1191,6 +1193,22 @@ EXPECT_EQ("input.cpp", Change.getFilePath()); } +TEST_F(AtomicChangeTest, Replace) { + setUp(); + AtomicChange Change(Context.Sources, DefaultLoc); + llvm::Error Err = Change.replace(Context.Sources, DefaultLoc, 2, "aa"); + ASSERT_TRUE(!Err); + EXPECT_EQ(Change.getReplacements().size(), 1u); + EXPECT_EQ(*Change.getReplacements().begin(), +Replacement(Context.Sources, DefaultLoc, 2, "aa")); + + // Add a new replacement that conflicts with the existing one. + Err = Change.replace(Context.Sources, DefaultLoc, 3, "ab"); + EXPECT_TRUE((bool)Err); + llvm::consumeError(std::move(Err)); + EXPECT_EQ(Change.getReplacements().size(), 1u); +} + TEST_F(AtomicChangeTest, InsertBefore) { setUp(); AtomicChange Change(Context.Sources, DefaultLoc); Index: lib/Tooling/Refactoring/AtomicChange.cpp === --- lib/Tooling/Refactoring/AtomicChange.cpp +++ lib/Tooling/Refactoring/AtomicChange.cpp @@ -132,6 +132,11 @@ return E; } +llvm::Error AtomicChange::replace(const SourceManager &SM, SourceLocation Loc, + unsigned Length, llvm::StringRef Text) { + return Replaces.add(Replacement(SM, Loc, Length, Text)); +} + llvm::Error AtomicChange::insert(const SourceManager &SM, SourceLocation Loc, llvm::StringRef Text, bool InsertAfter) { i
Re: [libunwind] r297175 - Tidy up the way we include EHHeaderParser.hpp.
Hi Marshall, 2017-03-08 15:47 GMT+01:00 Marshall Clow : > I'm having trouble building libunwind this morning (on a Mac). Ah, thanks for reporting. I only tested this on FreeBSD and CloudABI. On those systems we don't build Unwind_AppleExtras.cpp. > /Sources/LLVM/llvm/projects/libunwind/src/EHHeaderParser.hpp:44:32: error: > expected a qualified name after 'typename' > typename CFI_Parser::FDE_Info *fdeInfo, >^ Looking at the sources, I think this change introduced the cyclic dependency on #includes: AddressSpace.hpp -> EHHeaderParser.hpp -> DwarfParser.hpp -> AddressSpace.hpp. Though EHHeaderParser.hpp and DwarfParser.hpp both declare class templates that can take LocalAddressSpace as an argument, they don't have any actual source-level dependency on that class. We can therefore remove the #include to AddressSpace.hpp and only do that in Unwind_AppleExtras.cpp. What are your thoughts on the attached patch? -- Ed Schouten Nuxi, 's-Hertogenbosch, the Netherlands KvK-nr.: 62051717 Index: src/DwarfParser.hpp === --- src/DwarfParser.hpp (revision 297278) +++ src/DwarfParser.hpp (working copy) @@ -21,7 +21,6 @@ #include "libunwind.h" #include "dwarf2.h" -#include "AddressSpace.hpp" #include "config.h" namespace libunwind { Index: src/EHHeaderParser.hpp === --- src/EHHeaderParser.hpp (revision 297278) +++ src/EHHeaderParser.hpp (working copy) @@ -15,7 +15,6 @@ #include "libunwind.h" -#include "AddressSpace.hpp" #include "DwarfParser.hpp" namespace libunwind { Index: src/Unwind_AppleExtras.cpp === --- src/Unwind_AppleExtras.cpp (revision 297278) +++ src/Unwind_AppleExtras.cpp (working copy) @@ -9,6 +9,7 @@ //===--===// #include "config.h" +#include "AddressSpace.hpp" #include "DwarfParser.hpp" #include "unwind_ext.h" ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [libunwind] r297174 - Improve readability and correctness of the OS specific libunwind bits.
Hi Asiri, 2017-03-07 20:42 GMT+01:00 Asiri Rathnayake : > Could you please always include cfe-commits as a subscriber in you phab > reviews? > > We would like to be aware of these changes in advance before they land. Sure thing! I'll try to do that from now on. That said, if the policy is to add cfe-commits@ to all Clang/libunwind-related code reviews, would it make sense to configure Phabricator's Herald to set this up for us automatically? Looking at https://reviews.llvm.org/herald/new/, I suspect that can only be configured with admin rights. Regards, -- Ed Schouten Nuxi, 's-Hertogenbosch, the Netherlands KvK-nr.: 62051717 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30729: [ubsan] Skip range checks for width-limited values
arphaman added a comment. You should also add a test for `enum E : unsigned`. https://reviews.llvm.org/D30729 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297283 - [analyzer] Clarify 'uninitialized function argument' messages
Author: danielmarjamaki Date: Wed Mar 8 09:22:24 2017 New Revision: 297283 URL: http://llvm.org/viewvc/llvm-project?rev=297283&view=rev Log: [analyzer] Clarify 'uninitialized function argument' messages Differential Revision: https://reviews.llvm.org/D30341 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp cfe/trunk/test/Analysis/NewDelete-checker-test.cpp cfe/trunk/test/Analysis/diagnostics/undef-value-param.m cfe/trunk/test/Analysis/malloc.m cfe/trunk/test/Analysis/misc-ps-region-store.m cfe/trunk/test/Analysis/misc-ps.m cfe/trunk/test/Analysis/null-deref-ps.c cfe/trunk/test/Analysis/nullptr.cpp cfe/trunk/test/Analysis/uninit-const.c cfe/trunk/test/Analysis/uninit-const.cpp cfe/trunk/test/Analysis/uninit-msg-expr.m cfe/trunk/test/Analysis/uninit-vals-ps.c cfe/trunk/test/Analysis/uninit-vals.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp?rev=297283&r1=297282&r2=297283&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp Wed Mar 8 09:22:24 2017 @@ -21,6 +21,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -71,7 +72,7 @@ public: private: bool PreVisitProcessArg(CheckerContext &C, SVal V, SourceRange ArgRange, - const Expr *ArgEx, bool IsFirstArgument, + const Expr *ArgEx, int ArgumentNumber, bool CheckUninitFields, const CallEvent &Call, std::unique_ptr &BT, const ParmVarDecl *ParamDecl) const; @@ -89,9 +90,10 @@ private: BT.reset(new BuiltinBug(this, desc)); } bool uninitRefOrPointer(CheckerContext &C, const SVal &V, - SourceRange ArgRange, - const Expr *ArgEx, std::unique_ptr &BT, - const ParmVarDecl *ParamDecl, const char *BD) const; + SourceRange ArgRange, const Expr *ArgEx, + std::unique_ptr &BT, + const ParmVarDecl *ParamDecl, const char *BD, + int ArgumentNumber) const; }; } // end anonymous namespace @@ -111,38 +113,45 @@ void CallAndMessageChecker::emitBadCall( C.emitReport(std::move(R)); } -static StringRef describeUninitializedArgumentInCall(const CallEvent &Call, - bool IsFirstArgument) { +static void describeUninitializedArgumentInCall(const CallEvent &Call, +int ArgumentNumber, +llvm::raw_svector_ostream &Os) { switch (Call.getKind()) { case CE_ObjCMessage: { const ObjCMethodCall &Msg = cast(Call); switch (Msg.getMessageKind()) { case OCM_Message: - return "Argument in message expression is an uninitialized value"; + Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1) + << " argument in message expression is an uninitialized value"; + return; case OCM_PropertyAccess: assert(Msg.isSetter() && "Getters have no args"); - return "Argument for property setter is an uninitialized value"; + Os << "Argument for property setter is an uninitialized value"; + return; case OCM_Subscript: - if (Msg.isSetter() && IsFirstArgument) -return "Argument for subscript setter is an uninitialized value"; - return "Subscript index is an uninitialized value"; + if (Msg.isSetter() && (ArgumentNumber == 0)) +Os << "Argument for subscript setter is an uninitialized value"; + else +Os << "Subscript index is an uninitialized value"; + return; } llvm_unreachable("Unknown message kind."); } case CE_Block: -return "Block call argument is an uninitialized value"; +Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1) + << " block call argument is an uninitialized value"; +return; default: -return "Function call argument is an uninitialized value"; +Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1) + << " function call argument is an uninitialized value"; +return; } } -bool CallAndMessageChecker::uninitRefOrPointer(CheckerContext &C, - const SVal &V, - SourceRange ArgRange, -
[PATCH] D30341: [analyzer] clarify error messages about uninitialized function arguments
This revision was automatically updated to reflect the committed changes. Closed by commit rL297283: [analyzer] Clarify 'uninitialized function argument' messages (authored by danielmarjamaki). Changed prior to commit: https://reviews.llvm.org/D30341?vs=90471&id=91012#toc Repository: rL LLVM https://reviews.llvm.org/D30341 Files: cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp cfe/trunk/test/Analysis/NewDelete-checker-test.cpp cfe/trunk/test/Analysis/diagnostics/undef-value-param.m cfe/trunk/test/Analysis/malloc.m cfe/trunk/test/Analysis/misc-ps-region-store.m cfe/trunk/test/Analysis/misc-ps.m cfe/trunk/test/Analysis/null-deref-ps.c cfe/trunk/test/Analysis/nullptr.cpp cfe/trunk/test/Analysis/uninit-const.c cfe/trunk/test/Analysis/uninit-const.cpp cfe/trunk/test/Analysis/uninit-msg-expr.m cfe/trunk/test/Analysis/uninit-vals-ps.c cfe/trunk/test/Analysis/uninit-vals.cpp Index: cfe/trunk/test/Analysis/diagnostics/undef-value-param.m === --- cfe/trunk/test/Analysis/diagnostics/undef-value-param.m +++ cfe/trunk/test/Analysis/diagnostics/undef-value-param.m @@ -45,8 +45,8 @@ CreateRefUndef(&storeRef, 4); //expected-note@-1{{Calling 'CreateRefUndef'}} //expected-note@-2{{Returning from 'CreateRefUndef'}} -CFRelease(storeRef); //expected-warning {{Function call argument is an uninitialized value}} - //expected-note@-1{{Function call argument is an uninitialized value}} +CFRelease(storeRef); //expected-warning {{1st function call argument is an uninitialized value}} + //expected-note@-1{{1st function call argument is an uninitialized value}} } @end @@ -918,12 +918,12 @@ // CHECK-NEXT: // CHECK-NEXT: depth0 // CHECK-NEXT: extended_message -// CHECK-NEXT: Function call argument is an uninitialized value +// CHECK-NEXT: 1st function call argument is an uninitialized value // CHECK-NEXT: message -// CHECK-NEXT: Function call argument is an uninitialized value +// CHECK-NEXT: 1st function call argument is an uninitialized value // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT:descriptionFunction call argument is an uninitialized value +// CHECK-NEXT:description1st function call argument is an uninitialized value // CHECK-NEXT:categoryLogic error // CHECK-NEXT:typeUninitialized argument value // CHECK-NEXT:check_namecore.CallAndMessage Index: cfe/trunk/test/Analysis/null-deref-ps.c === --- cfe/trunk/test/Analysis/null-deref-ps.c +++ cfe/trunk/test/Analysis/null-deref-ps.c @@ -286,7 +286,7 @@ void pr4759() { int *p; - pr4759_aux(p); // expected-warning{{Function call argument is an uninitialized value}} + pr4759_aux(p); // expected-warning{{1st function call argument is an uninitialized value}} } // Relax function call arguments invalidation to be aware of const Index: cfe/trunk/test/Analysis/uninit-const.c === --- cfe/trunk/test/Analysis/uninit-const.c +++ cfe/trunk/test/Analysis/uninit-const.c @@ -24,16 +24,16 @@ void f_1(void) { int t; int* tp = &t;// expected-note {{'tp' initialized here}} - doStuff_pointerToConstInt(tp); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_pointerToConstInt(tp); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } void f_1_1(void) { int t; int* tp1 = &t; int* tp2 = tp1;// expected-note {{'tp2' initialized here}} - doStuff_pointerToConstInt(tp2); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_pointerToConstInt(tp2); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } @@ -45,8 +45,8 @@ int t; int* p = f_2_sub(&t); int* tp = p; // expected-note {{'tp' initialized here}} - doStuff_pointerToConstInt(tp); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_pointerToConstInt(tp); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninit
[PATCH] D30675: [clangd] Fix not being able to attach a debugger on macOS
malaperle-ericsson added a comment. In https://reviews.llvm.org/D30675#695370, @bkramer wrote: > Generally makes sense. Is there any reason for the #ifdef? Windows has errno > and EINTR too. I have no reasonable expectation that getline will produce a EINTR on Windows. But perhaps there's no harm in doing so? What is you preference? Repository: rL LLVM https://reviews.llvm.org/D30675 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30423: [ubsan] Detect UB loads from bitfields
filcab added inline comments. Comment at: test/CodeGenObjC/ubsan-bool.m:26 + // OBJC: [[ICMP:%.*]] = icmp ule i8 [[ASHR]], 1, !nosanitize + // OBJC: call void @__ubsan_handle_load_invalid_value + jroelofs wrote: > vsk wrote: > > jroelofs wrote: > > > vsk wrote: > > > > arphaman wrote: > > > > > Is it possible to avoid the check here since the bitfield is just one > > > > > bit wide? > > > > No, a user could do: > > > > > > > > ``` > > > > struct S1 s; > > > > s.b1 = 1; > > > > if (s.b1 == 1) // evaluates to false, s.b1 is negative > > > > ``` > > > > > > > > With this patch we get: > > > > ``` > > > > runtime error: load of value -1, which is not a valid value for type > > > > 'BOOL' (aka 'signed char') > > > > ``` > > > What if BOOL is an `unsigned char`, or a `char` that's not signed? > > Good point, we don't need to emit the range check if the bitfield is an > > unsigned, 1-bit wide BOOL. Would you be OK with me tackling that in a > > follow-up patch? > No problem, sounds good to me. I don't like generating an error here. -1 is a perfectly valid BOOL (signed char) value and it's a perfectly valid value to have in a (signed) 1-wide bitfield. Comment at: test/CodeGenObjC/ubsan-bool.m:50 +// OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7 +// OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7 +// OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize jroelofs wrote: > hmmm. just occurred to me that this value is always going to be 0xff or 0x0, > so it might be useful if there were also a frontend warning that complains > about signed bitfield bools (maybe something useful for another patch). I'm more ok with this, assuming it makes sense in ObjC. https://reviews.llvm.org/D30423 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30735: Add missing implementation for AtomicChange::replace(...)
klimek accepted this revision. klimek added a comment. This revision is now accepted and ready to land. lg https://reviews.llvm.org/D30735 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297289 - Add missing implementation for AtomicChange::replace(...)
Author: ioeric Date: Wed Mar 8 09:53:10 2017 New Revision: 297289 URL: http://llvm.org/viewvc/llvm-project?rev=297289&view=rev Log: Add missing implementation for AtomicChange::replace(...) Summary: Just realized the implementation is missing... Reviewers: klimek Reviewed By: klimek Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D30735 Modified: cfe/trunk/lib/Tooling/Refactoring/AtomicChange.cpp cfe/trunk/unittests/Tooling/RefactoringTest.cpp Modified: cfe/trunk/lib/Tooling/Refactoring/AtomicChange.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/AtomicChange.cpp?rev=297289&r1=297288&r2=297289&view=diff == --- cfe/trunk/lib/Tooling/Refactoring/AtomicChange.cpp (original) +++ cfe/trunk/lib/Tooling/Refactoring/AtomicChange.cpp Wed Mar 8 09:53:10 2017 @@ -132,6 +132,11 @@ AtomicChange AtomicChange::convertFromYA return E; } +llvm::Error AtomicChange::replace(const SourceManager &SM, SourceLocation Loc, + unsigned Length, llvm::StringRef Text) { + return Replaces.add(Replacement(SM, Loc, Length, Text)); +} + llvm::Error AtomicChange::insert(const SourceManager &SM, SourceLocation Loc, llvm::StringRef Text, bool InsertAfter) { if (Text.empty()) Modified: cfe/trunk/unittests/Tooling/RefactoringTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/RefactoringTest.cpp?rev=297289&r1=297288&r2=297289&view=diff == --- cfe/trunk/unittests/Tooling/RefactoringTest.cpp (original) +++ cfe/trunk/unittests/Tooling/RefactoringTest.cpp Wed Mar 8 09:53:10 2017 @@ -1173,8 +1173,10 @@ TEST_F(AtomicChangeTest, YAMLToAtomicCha EXPECT_EQ(ExpectedChange.getKey(), ActualChange.getKey()); EXPECT_EQ(ExpectedChange.getFilePath(), ActualChange.getFilePath()); EXPECT_EQ(ExpectedChange.getError(), ActualChange.getError()); - EXPECT_EQ(ExpectedChange.getInsertedHeaders(), ActualChange.getInsertedHeaders()); - EXPECT_EQ(ExpectedChange.getRemovedHeaders(), ActualChange.getRemovedHeaders()); + EXPECT_EQ(ExpectedChange.getInsertedHeaders(), +ActualChange.getInsertedHeaders()); + EXPECT_EQ(ExpectedChange.getRemovedHeaders(), +ActualChange.getRemovedHeaders()); EXPECT_EQ(ExpectedChange.getReplacements().size(), ActualChange.getReplacements().size()); EXPECT_EQ(2u, ActualChange.getReplacements().size()); @@ -1191,6 +1193,22 @@ TEST_F(AtomicChangeTest, CheckKeyAndKeyF EXPECT_EQ("input.cpp", Change.getFilePath()); } +TEST_F(AtomicChangeTest, Replace) { + setUp(); + AtomicChange Change(Context.Sources, DefaultLoc); + llvm::Error Err = Change.replace(Context.Sources, DefaultLoc, 2, "aa"); + ASSERT_TRUE(!Err); + EXPECT_EQ(Change.getReplacements().size(), 1u); + EXPECT_EQ(*Change.getReplacements().begin(), +Replacement(Context.Sources, DefaultLoc, 2, "aa")); + + // Add a new replacement that conflicts with the existing one. + Err = Change.replace(Context.Sources, DefaultLoc, 3, "ab"); + EXPECT_TRUE((bool)Err); + llvm::consumeError(std::move(Err)); + EXPECT_EQ(Change.getReplacements().size(), 1u); +} + TEST_F(AtomicChangeTest, InsertBefore) { setUp(); AtomicChange Change(Context.Sources, DefaultLoc); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30735: Add missing implementation for AtomicChange::replace(...)
This revision was automatically updated to reflect the committed changes. Closed by commit rL297289: Add missing implementation for AtomicChange::replace(...) (authored by ioeric). Changed prior to commit: https://reviews.llvm.org/D30735?vs=91010&id=91020#toc Repository: rL LLVM https://reviews.llvm.org/D30735 Files: cfe/trunk/lib/Tooling/Refactoring/AtomicChange.cpp cfe/trunk/unittests/Tooling/RefactoringTest.cpp Index: cfe/trunk/lib/Tooling/Refactoring/AtomicChange.cpp === --- cfe/trunk/lib/Tooling/Refactoring/AtomicChange.cpp +++ cfe/trunk/lib/Tooling/Refactoring/AtomicChange.cpp @@ -132,6 +132,11 @@ return E; } +llvm::Error AtomicChange::replace(const SourceManager &SM, SourceLocation Loc, + unsigned Length, llvm::StringRef Text) { + return Replaces.add(Replacement(SM, Loc, Length, Text)); +} + llvm::Error AtomicChange::insert(const SourceManager &SM, SourceLocation Loc, llvm::StringRef Text, bool InsertAfter) { if (Text.empty()) Index: cfe/trunk/unittests/Tooling/RefactoringTest.cpp === --- cfe/trunk/unittests/Tooling/RefactoringTest.cpp +++ cfe/trunk/unittests/Tooling/RefactoringTest.cpp @@ -1173,8 +1173,10 @@ EXPECT_EQ(ExpectedChange.getKey(), ActualChange.getKey()); EXPECT_EQ(ExpectedChange.getFilePath(), ActualChange.getFilePath()); EXPECT_EQ(ExpectedChange.getError(), ActualChange.getError()); - EXPECT_EQ(ExpectedChange.getInsertedHeaders(), ActualChange.getInsertedHeaders()); - EXPECT_EQ(ExpectedChange.getRemovedHeaders(), ActualChange.getRemovedHeaders()); + EXPECT_EQ(ExpectedChange.getInsertedHeaders(), +ActualChange.getInsertedHeaders()); + EXPECT_EQ(ExpectedChange.getRemovedHeaders(), +ActualChange.getRemovedHeaders()); EXPECT_EQ(ExpectedChange.getReplacements().size(), ActualChange.getReplacements().size()); EXPECT_EQ(2u, ActualChange.getReplacements().size()); @@ -1191,6 +1193,22 @@ EXPECT_EQ("input.cpp", Change.getFilePath()); } +TEST_F(AtomicChangeTest, Replace) { + setUp(); + AtomicChange Change(Context.Sources, DefaultLoc); + llvm::Error Err = Change.replace(Context.Sources, DefaultLoc, 2, "aa"); + ASSERT_TRUE(!Err); + EXPECT_EQ(Change.getReplacements().size(), 1u); + EXPECT_EQ(*Change.getReplacements().begin(), +Replacement(Context.Sources, DefaultLoc, 2, "aa")); + + // Add a new replacement that conflicts with the existing one. + Err = Change.replace(Context.Sources, DefaultLoc, 3, "ab"); + EXPECT_TRUE((bool)Err); + llvm::consumeError(std::move(Err)); + EXPECT_EQ(Change.getReplacements().size(), 1u); +} + TEST_F(AtomicChangeTest, InsertBefore) { setUp(); AtomicChange Change(Context.Sources, DefaultLoc); Index: cfe/trunk/lib/Tooling/Refactoring/AtomicChange.cpp === --- cfe/trunk/lib/Tooling/Refactoring/AtomicChange.cpp +++ cfe/trunk/lib/Tooling/Refactoring/AtomicChange.cpp @@ -132,6 +132,11 @@ return E; } +llvm::Error AtomicChange::replace(const SourceManager &SM, SourceLocation Loc, + unsigned Length, llvm::StringRef Text) { + return Replaces.add(Replacement(SM, Loc, Length, Text)); +} + llvm::Error AtomicChange::insert(const SourceManager &SM, SourceLocation Loc, llvm::StringRef Text, bool InsertAfter) { if (Text.empty()) Index: cfe/trunk/unittests/Tooling/RefactoringTest.cpp === --- cfe/trunk/unittests/Tooling/RefactoringTest.cpp +++ cfe/trunk/unittests/Tooling/RefactoringTest.cpp @@ -1173,8 +1173,10 @@ EXPECT_EQ(ExpectedChange.getKey(), ActualChange.getKey()); EXPECT_EQ(ExpectedChange.getFilePath(), ActualChange.getFilePath()); EXPECT_EQ(ExpectedChange.getError(), ActualChange.getError()); - EXPECT_EQ(ExpectedChange.getInsertedHeaders(), ActualChange.getInsertedHeaders()); - EXPECT_EQ(ExpectedChange.getRemovedHeaders(), ActualChange.getRemovedHeaders()); + EXPECT_EQ(ExpectedChange.getInsertedHeaders(), +ActualChange.getInsertedHeaders()); + EXPECT_EQ(ExpectedChange.getRemovedHeaders(), +ActualChange.getRemovedHeaders()); EXPECT_EQ(ExpectedChange.getReplacements().size(), ActualChange.getReplacements().size()); EXPECT_EQ(2u, ActualChange.getReplacements().size()); @@ -1191,6 +1193,22 @@ EXPECT_EQ("input.cpp", Change.getFilePath()); } +TEST_F(AtomicChangeTest, Replace) { + setUp(); + AtomicChange Change(Context.Sources, DefaultLoc); + llvm::Error Err = Change.replace(Context.Sources, DefaultLoc, 2, "aa"); + ASSERT_TRUE(!Err); + EXPECT_EQ(Change.getReplacements().size(), 1u); + EXPECT_EQ(*Change.getReplacements().begin(), +Replacement(Context.Sources, DefaultLoc, 2, "aa")); + + // Add a new
[libunwind] r297291 - DARWF: silence some warnings about conversions
Author: compnerd Date: Wed Mar 8 10:03:27 2017 New Revision: 297291 URL: http://llvm.org/viewvc/llvm-project?rev=297291&view=rev Log: DARWF: silence some warnings about conversions Add a check for an overflow and explicitly cast the value. We would have silently overflowed previously. Modified: libunwind/trunk/src/DwarfInstructions.hpp libunwind/trunk/src/DwarfParser.hpp Modified: libunwind/trunk/src/DwarfInstructions.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/DwarfInstructions.hpp?rev=297291&r1=297290&r2=297291&view=diff == --- libunwind/trunk/src/DwarfInstructions.hpp (original) +++ libunwind/trunk/src/DwarfInstructions.hpp Wed Mar 8 10:03:27 2017 @@ -480,7 +480,7 @@ DwarfInstructions::evaluateExpress case DW_OP_plus_uconst: // pop stack, add uelb128 constant, push result - *sp += addressSpace.getULEB128(p, expressionEnd); + *sp += static_cast(addressSpace.getULEB128(p, expressionEnd)); if (log) fprintf(stderr, "add constant\n"); break; Modified: libunwind/trunk/src/DwarfParser.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/DwarfParser.hpp?rev=297291&r1=297290&r2=297291&view=diff == --- libunwind/trunk/src/DwarfParser.hpp (original) +++ libunwind/trunk/src/DwarfParser.hpp Wed Mar 8 10:03:27 2017 @@ -542,7 +542,8 @@ bool CFI_Parser::parseInstructions(A results->cfaRegister = 0; results->cfaExpression = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - p += length; + assert(length < std::numeric_limits::max() && "pointer overflow"); + p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_expression(expression=0x%" PRIx64 ", length=%" PRIu64 ")\n", results->cfaExpression, length); @@ -557,7 +558,8 @@ bool CFI_Parser::parseInstructions(A results->savedRegisters[reg].location = kRegisterAtExpression; results->savedRegisters[reg].value = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - p += length; + assert(length < std::numeric_limits::max() && "pointer overflow"); + p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_expression(reg=%" PRIu64 ", " "expression=0x%" PRIx64 ", " "length=%" PRIu64 ")\n", @@ -636,7 +638,8 @@ bool CFI_Parser::parseInstructions(A results->savedRegisters[reg].location = kRegisterIsExpression; results->savedRegisters[reg].value = (int64_t)p; length = addressSpace.getULEB128(p, instructionsEnd); - p += length; + assert(length < std::numeric_limits::max() && "pointer overflow"); + p += static_cast(length); _LIBUNWIND_TRACE_DWARF("DW_CFA_val_expression(reg=%" PRIu64 ", " "expression=0x%" PRIx64 ", length=%" PRIu64 ")\n", reg, results->savedRegisters[reg].value, length); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30739: [OpenMP] "declare simd" for AArch64 Advanced SIMD.
fpetrogalli created this revision. Herald added subscribers: rengolin, aemerson. This patch enables the code generation of vector function names that are described by attaching a "#pragma omp declare simd" directive to the scalar function definition/declaration, for the Advanced SIMD (NEON) vector extension of the A64 instruction set for the AArch64 execution state of the ARMv8 architecture. As it is done for other targets, the available vector functions are stored as string attributes attached to the scalar function in the IR, and are made available for further processing in the middle end (e.g. exposure to the loop vectorizer). The mangling function of the vector names is compatible with the Itanium-standard names that are being generated for X86. The value of the token that specifies the architecture extension is 'n' - as for NEON. Changes --- - The `SimdDefaultAlign` value of the AArch64TargetInfo class has been set to 128-bit - the size of a quad-word register "Q" for NEON. - The name mangling function for X86 has been merged into a generic one that is shared with AArch64, as `emitTargetDeclareSimdFunction`. - The CodeGen test has been split into X86 and AArch64 runs. - To improve readability and maintainability, the actual FileCheck checks (both for X86 and AArch64) have been moved right after the respective function declarations. Note The patch does not introduce any functional change for the X86 target. https://reviews.llvm.org/D30739 Files: lib/Basic/Targets.cpp lib/CodeGen/CGOpenMPRuntime.cpp test/OpenMP/declare_simd_codegen.cpp Index: test/OpenMP/declare_simd_codegen.cpp === --- test/OpenMP/declare_simd_codegen.cpp +++ test/OpenMP/declare_simd_codegen.cpp @@ -1,15 +1,86 @@ -// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - -femit-all-decls | FileCheck %s +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - -femit-all-decls | FileCheck --check-prefix=X86 %s // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls | FileCheck --check-prefix=X86 %s + +// RUN: %clang_cc1 -verify -triple aarch64-linux-gnu -fopenmp -x c++ -emit-llvm %s -o - -femit-all-decls | FileCheck --check-prefix=AARCH64 %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple aarch64-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple aarch64-linux-gnu -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls | FileCheck --check-prefix=AARCH64 %s + // expected-no-diagnostics + +// X86-DAG: define {{.+}}@_Z5add_1Pf( +// X86-DAG: define {{.+}}@_Z1hIiEvPT_S1_S1_S1_( +// X86-DAG: define {{.+}}@_Z1hIfEvPT_S1_S1_S1_( +// X86-DAG: define {{.+}}@_ZN2VV3addEii( +// X86-DAG: define {{.+}}@_ZN2VV6taddpfEPfRS0_( +// X86-DAG: define {{.+}}@_ZN2VV4taddERA_iRi( +// X86-DAG: define {{.+}}@_Z1fRA_i( +// X86-DAG: define {{.+}}@_ZN3TVVILi16EfE6taddpfEPfRS1_( +// X86-DAG: define {{.+}}@_ZN3TVVILi16EfE4taddEi( +// X86-DAG: define {{.+}}@_Z3fooILi64EEvRAT__iRPf( +// X86-DAG: define {{.+}}@_Z3bar2VVPf( +// X86-DAG: define {{.+}}@_Z3baz2VVPi( +// X86-DAG: define {{.+}}@_Z3bay2VVRPd( +// X86-DAG: define {{.+}}@_Z3bax2VVPdi( +// X86-DAG: define {{.+}}@_Z3fooPffi( +// X86-DAG: define {{.+}}@_Z3food( +// X86-NOT: "_ZGV{{.+}}__Z1fRA_i + +// AARCH64-DAG: define {{.+}}@_Z5add_1Pf( +// AARCH64-DAG: define {{.+}}@_Z1hIiEvPT_S1_S1_S1_( +// AARCH64-DAG: define {{.+}}@_Z1hIfEvPT_S1_S1_S1_( +// AARCH64-DAG: define {{.+}}@_ZN2VV3addEii( +// AARCH64-DAG: define {{.+}}@_ZN2VV6taddpfEPfRS0_( +// AARCH64-DAG: define {{.+}}@_ZN2VV4taddERA_iRi( +// AARCH64-DAG: define {{.+}}@_Z1fRA_i( +// AARCH64-DAG: define {{.+}}@_ZN3TVVILi16EfE6taddpfEPfRS1_( +// AARCH64-DAG: define {{.+}}@_ZN3TVVILi16EfE4taddEi( +// AARCH64-DAG: define {{.+}}@_Z3fooILi64EEvRAT__iRPf( +// AARCH64-DAG: define {{.+}}@_Z3bar2VVPf( +// AARCH64-DAG: define {{.+}}@_Z3baz2VVPi( +// AARCH64-DAG: define {{.+}}@_Z3bay2VVRPd( +// AARCH64-DAG: define {{.+}}@_Z3bax2VVPdi( +// AARCH64-DAG: define {{.+}}@_Z3fooPffi( +// AARCH64-DAG: define {{.+}}@_Z3food( +// AARCH64-NOT: "_ZGV{{.+}}__Z1fRA_i + #ifndef HEADER #define HEADER #pragma omp declare simd linear(d : 8) #pragma omp declare simd inbranch simdlen(32) #pragma omp declare simd notinbranch void add_1(float *d) {} +// X86-DAG: "_ZGVbM4l8__Z5add_1Pf" +// X86-DAG: "_ZGVbN4l8__Z5add_1Pf" +// X86-DAG: "_ZGVcM8l8__Z5add_1Pf" +// X86-DAG: "_ZGVcN8l8__Z5add_1Pf" +// X86-DAG: "_ZGVdM8l8__Z5add_1Pf" +// X86-DAG: "_ZGVdN8l8__Z5add_1Pf" +// X86-DAG: "_ZGVeM16l8__Z5add_1Pf" +// X86-DAG: "_ZGVeN16l8__Z5add_1Pf" +// X86-DAG: "_ZGVbM32v__Z5add_1Pf" +// X86-DAG: "_ZGVcM32v__Z5add_1Pf" +// X86-
[PATCH] D30729: [ubsan] Skip range checks for width-limited values
filcab added inline comments. Comment at: test/CodeGenCXX/ubsan-bitfields.cpp:39 + // CHECK-NOT: !nosanitize + return s->e3; +} Add checks/check-nots to make sure the thing you don't want isn't emitted, not just `!nosanitize` The checks help document what you're trying to get in each test case. Here I'd prefer to have a `CHECK-NOT: __ubsan_handle_load_invalid_value` than a check-not for `!nosanitize`, since checking for the handler call is more explicit. https://reviews.llvm.org/D30729 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30740: Remove a useless subsitution in doxygen2rst which was incorrectly replacing * by \*
sylvestre.ledru created this revision. For example, "int\* a;" is displayed instead of "int* a;" https://reviews.llvm.org/D30740 Files: docs/ClangFormatStyleOptions.rst docs/tools/dump_format_style.py Index: docs/ClangFormatStyleOptions.rst === --- docs/ClangFormatStyleOptions.rst +++ docs/ClangFormatStyleOptions.rst @@ -585,7 +585,7 @@ **DerivePointerAlignment** (``bool``) If ``true``, analyze the formatted file for the most common - alignment of ``&`` and ``\*``. ``PointerAlignment`` is then used only as + alignment of ``&`` and ``*``. ``PointerAlignment`` is then used only as fallback. **DisableFormat** (``bool``) @@ -659,7 +659,7 @@ Priority:2 - Regex: '^(<|"(gtest|isl|json)/)' Priority:3 - - Regex: '.\*' + - Regex: '.*' Priority:1 **IncludeIsMainRegex** (``std::string``) @@ -804,7 +804,7 @@ .. code-block:: c++ - int\* a; + int* a; * ``PAS_Right`` (in configuration: ``Right``) Align pointer to the right. @@ -811,7 +811,7 @@ .. code-block:: c++ - int \*a; + int *a; * ``PAS_Middle`` (in configuration: ``Middle``) Align pointer in the middle. @@ -818,7 +818,7 @@ .. code-block:: c++ - int \* a; + int * a; Index: docs/tools/dump_format_style.py === --- docs/tools/dump_format_style.py +++ docs/tools/dump_format_style.py @@ -19,7 +19,6 @@ return re.sub(pattern, '%s', text, flags=re.S) % replacement def doxygen2rst(text): - text = re.sub(r'([^/\*])\*', r'\1\\*', text) text = re.sub(r'\s*(.*?)\s*<\/tt>', r'``\1``', text) text = re.sub(r'\\c ([^ ,;\.]+)', r'``\1``', text) text = re.sub(r'\\\w+ ', '', text) Index: docs/ClangFormatStyleOptions.rst === --- docs/ClangFormatStyleOptions.rst +++ docs/ClangFormatStyleOptions.rst @@ -585,7 +585,7 @@ **DerivePointerAlignment** (``bool``) If ``true``, analyze the formatted file for the most common - alignment of ``&`` and ``\*``. ``PointerAlignment`` is then used only as + alignment of ``&`` and ``*``. ``PointerAlignment`` is then used only as fallback. **DisableFormat** (``bool``) @@ -659,7 +659,7 @@ Priority:2 - Regex: '^(<|"(gtest|isl|json)/)' Priority:3 - - Regex: '.\*' + - Regex: '.*' Priority:1 **IncludeIsMainRegex** (``std::string``) @@ -804,7 +804,7 @@ .. code-block:: c++ - int\* a; + int* a; * ``PAS_Right`` (in configuration: ``Right``) Align pointer to the right. @@ -811,7 +811,7 @@ .. code-block:: c++ - int \*a; + int *a; * ``PAS_Middle`` (in configuration: ``Middle``) Align pointer in the middle. @@ -818,7 +818,7 @@ .. code-block:: c++ - int \* a; + int * a; Index: docs/tools/dump_format_style.py === --- docs/tools/dump_format_style.py +++ docs/tools/dump_format_style.py @@ -19,7 +19,6 @@ return re.sub(pattern, '%s', text, flags=re.S) % replacement def doxygen2rst(text): - text = re.sub(r'([^/\*])\*', r'\1\\*', text) text = re.sub(r'\s*(.*?)\s*<\/tt>', r'``\1``', text) text = re.sub(r'\\c ([^ ,;\.]+)', r'``\1``', text) text = re.sub(r'\\\w+ ', '', text) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30685: [include-fixer] Remove line number from Symbol identity
hokein accepted this revision. hokein added a comment. This revision is now accepted and ready to land. LGTM once Ben has no other comments. Be careful before submitting it (this patch also changes the interface). https://reviews.llvm.org/D30685 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [libunwind] r297174 - Improve readability and correctness of the OS specific libunwind bits.
@Renato: What's your take on Ed's idea? We use phab for all sorts of reviews, but it should be possible to figure out which repository a review is intended to land on and add cfe-commits or llvm-commits appropriately. Although, for throw-away reviews, it might generate too much spam. Cheers, / Asiri On Wed, Mar 8, 2017 at 3:18 PM, Ed Schouten wrote: > Hi Asiri, > > 2017-03-07 20:42 GMT+01:00 Asiri Rathnayake : > > Could you please always include cfe-commits as a subscriber in you phab > > reviews? > > > > We would like to be aware of these changes in advance before they land. > > Sure thing! I'll try to do that from now on. > > That said, if the policy is to add cfe-commits@ to all > Clang/libunwind-related code reviews, would it make sense to configure > Phabricator's Herald to set this up for us automatically? Looking at > https://reviews.llvm.org/herald/new/, I suspect that can only be > configured with admin rights. > > Regards, > -- > Ed Schouten > Nuxi, 's-Hertogenbosch, the Netherlands > KvK-nr.: 62051717 > ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30739: [OpenMP] "declare simd" for AArch64 Advanced SIMD.
fhahn added inline comments. Comment at: lib/CodeGen/CGOpenMPRuntime.cpp:6664 + + static void + emitTargetDeclareSimdFunction(const FunctionDecl *FD, llvm::Function *Fn, Shouldn't this indentation be on the same level as namespace{}? https://reviews.llvm.org/D30739 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30423: [ubsan] Detect UB loads from bitfields
vsk added inline comments. Comment at: test/CodeGenObjC/ubsan-bool.m:26 + // OBJC: [[ICMP:%.*]] = icmp ule i8 [[ASHR]], 1, !nosanitize + // OBJC: call void @__ubsan_handle_load_invalid_value + filcab wrote: > jroelofs wrote: > > vsk wrote: > > > jroelofs wrote: > > > > vsk wrote: > > > > > arphaman wrote: > > > > > > Is it possible to avoid the check here since the bitfield is just > > > > > > one bit wide? > > > > > No, a user could do: > > > > > > > > > > ``` > > > > > struct S1 s; > > > > > s.b1 = 1; > > > > > if (s.b1 == 1) // evaluates to false, s.b1 is negative > > > > > ``` > > > > > > > > > > With this patch we get: > > > > > ``` > > > > > runtime error: load of value -1, which is not a valid value for type > > > > > 'BOOL' (aka 'signed char') > > > > > ``` > > > > What if BOOL is an `unsigned char`, or a `char` that's not signed? > > > Good point, we don't need to emit the range check if the bitfield is an > > > unsigned, 1-bit wide BOOL. Would you be OK with me tackling that in a > > > follow-up patch? > > No problem, sounds good to me. > I don't like generating an error here. > -1 is a perfectly valid BOOL (signed char) value and it's a perfectly valid > value to have in a (signed) 1-wide bitfield. True/false should be the only values loaded from a boolean. Since we made ubsan stricter about the range of BOOL (r289290), the check has caught a lot of bugs in our software. Specifically, it's helped root out buggy BOOL initialization and portability problems (the signedness of BOOL is not consistent on Apple platforms). There have been no false positives so far. Is this an issue you think needs to be addressed in this patch? Comment at: test/CodeGenObjC/ubsan-bool.m:50 +// OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7 +// OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7 +// OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize filcab wrote: > jroelofs wrote: > > hmmm. just occurred to me that this value is always going to be 0xff or > > 0x0, so it might be useful if there were also a frontend warning that > > complains about signed bitfield bools (maybe something useful for another > > patch). > I'm more ok with this, assuming it makes sense in ObjC. Yes, we have an internal feature request for such a warning. https://reviews.llvm.org/D30423 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30720: [include-fixer] Add fuzzy SymbolIndex, where identifier needn't match exactly.
hokein added inline comments. Comment at: include-fixer/FuzzySymbolIndex.cpp:138 +return llvm::errorCodeToError(Buffer.getError()); + return std::unique_ptr(new MemSymbolIndex( + find_all_symbols::ReadSymbolInfosFromYAML(Buffer.get()->getBuffer(; nit: `llvm::make_unique`. Comment at: include-fixer/FuzzySymbolIndex.h:54 +} // namespace clang +#endif nit: an empty line before `#endif` and trailing `// LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_FUZZY_SYMBOL_INDEX_H`. Comment at: include-fixer/SymbolIndexManager.cpp:106 // Match the identifier name without qualifier. - if (Symbol.getName() == Names.back()) { -bool IsMatched = true; Just want to verify: this judgement is not needed as it is guaranteed in Line 96 `DB.get()->search(Names.back())` right? Comment at: include-fixer/SymbolIndexManager.cpp:156 for (const auto &SymAndSig : MatchedSymbols) Res.push_back(std::move(SymAndSig.Symbol)); return Res; An off-topic catch: std::move should not work for `const auto &`, remove the `const`. Comment at: include-fixer/tool/ClangIncludeFixer.cpp:233 + return std::move(*DB); +}); + } I'd prefer to add a `break;` statement although this case is the last one. https://reviews.llvm.org/D30720 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30729: [ubsan] Skip range checks for width-limited values
vsk added a comment. In https://reviews.llvm.org/D30729#695463, @arphaman wrote: > You should also add a test for `enum E : unsigned`. Ubsan doesn't try to infer the range of enums with a fixed, underlying type. I'll add a test case to make sure we don't insert a check. Comment at: test/CodeGenCXX/ubsan-bitfields.cpp:39 + // CHECK-NOT: !nosanitize + return s->e3; +} filcab wrote: > Add checks/check-nots to make sure the thing you don't want isn't emitted, > not just `!nosanitize` > The checks help document what you're trying to get in each test case. > Here I'd prefer to have a `CHECK-NOT: __ubsan_handle_load_invalid_value` than > a check-not for `!nosanitize`, since checking for the handler call is more > explicit. > Good point, I will update the patch shortly. https://reviews.llvm.org/D30729 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30729: [ubsan] Skip range checks for width-limited values
vsk updated this revision to Diff 91030. vsk added a comment. - Make check-not's a bit stricter per Filipe's comment. - Add a negative test for fixed enums. https://reviews.llvm.org/D30729 Files: lib/CodeGen/CGExpr.cpp lib/CodeGen/CodeGenFunction.h test/CodeGenCXX/ubsan-bitfields.cpp Index: test/CodeGenCXX/ubsan-bitfields.cpp === --- test/CodeGenCXX/ubsan-bitfields.cpp +++ test/CodeGenCXX/ubsan-bitfields.cpp @@ -7,7 +7,9 @@ }; struct S { - E e1 : 10; + E e1 : 10; //< Wide enough for the unsigned range check. + E e2 : 2; //< Emit the check, since -1 = 3 = 0b11. + E e3 : 1; //< Skip the check. }; // CHECK-LABEL: define i32 @_Z4loadP1S @@ -19,3 +21,87 @@ // CHECK: call void @__ubsan_handle_load_invalid_value return s->e1; } + +// CHECK-LABEL: define i32 @_Z5load2P1S +E load2(S *s) { + // CHECK: [[LOAD:%.*]] = load i16, i16* {{.*}} + // CHECK: [[LSHR:%.*]] = lshr i16 [[LOAD]], 10 + // CHECK: [[CLEAR:%.*]] = and i16 [[LSHR]], 3 + // CHECK: [[CAST:%.*]] = zext i16 [[CLEAR]] to i32 + // CHECK: icmp ule i32 [[CAST]], 3, !nosanitize + // CHECK: call void @__ubsan_handle_load_invalid_value + return s->e2; +} + +// CHECK-LABEL: define i32 @_Z5load3P1S +E load3(S *s) { + // CHECK-NOT: __ubsan_handle_load_invalid_value + // CHECK-NOT: !nosanitize + return s->e3; +} + +enum E2 { + x = -3, + y = 3 +}; + +struct S2 { + E2 e1 : 4; //< Wide enough for signed range checks. + E2 e2 : 3; //< Skip the check, since the range of the bitfield is the same + // as the range of the enum: [-4, 3]. + E2 e3 : 2; //< Still skip the check. +}; + +// CHECK-LABEL: define i32 @_Z5load4P2S2 +E2 load4(S2 *s) { + // CHECK: [[LOAD:%.*]] = load i16, i16* {{.*}} + // CHECK: [[SHL:%.*]] = shl i16 [[LOAD]], 12 + // CHECK: [[ASHR:%.*]] = ashr i16 [[SHL]], 12 + // CHECK: [[CAST:%.*]] = sext i16 [[ASHR]] to i32 + // CHECK: [[UPPER_BOUND:%.*]] = icmp sle i32 [[CAST]], 3, !nosanitize + // CHECK: [[LOWER_BOUND:%.*]] = icmp sge i32 [[CAST]], -4, !nosanitize + // CHECK: [[BOUND:%.*]] = and i1 [[UPPER_BOUND]], [[LOWER_BOUND]], !nosanitize + // CHECK: br i1 [[BOUND]], {{.*}}, !nosanitize + // CHECK: call void @__ubsan_handle_load_invalid_value + return s->e1; +} + +// CHECK-LABEL: define i32 @_Z5load5P2S2 +E2 load5(S2 *s) { + // CHECK-NOT: __ubsan_handle_load_invalid_value + // CHECK-NOT: !nosanitize + return s->e2; +} + +// CHECK-LABEL: define i32 @_Z5load6P2S2 +E2 load6(S2 *s) { + // CHECK-NOT: __ubsan_handle_load_invalid_value + // CHECK-NOT: !nosanitize + return s->e3; +} + +// ubsan does not attempt to guess the range of fixed enums, i.e enums with a +// fixed, underlying type. Check that we don't emit range checks for it. +enum E3 : unsigned { + q = 1, + p = 3 +}; + +struct S3 { + E3 e1 : 3; + E3 e2 : 2; +}; + +// CHECK-LABEL: define i32 @_Z5load7P2S3 +E3 load7(S3 *s) { + // CHECK-NOT: __ubsan_handle_load_invalid_value + // CHECK-NOT: !nosanitize + return s->e1; +} + +// CHECK-LABEL: define i32 @_Z5load8P2S3 +E3 load8(S3 *s) { + // CHECK-NOT: __ubsan_handle_load_invalid_value + // CHECK-NOT: !nosanitize + return s->e2; +} Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -2892,11 +2892,12 @@ llvm::Value *EmitFromMemory(llvm::Value *Value, QualType Ty); /// Check if the scalar \p Value is within the valid range for the given - /// type \p Ty. + /// type \p Ty. If \p BitWidth is provided, it must be the bit width of the + /// storage for the scalar. /// - /// Returns true if a check is needed (even if the range is unknown). - bool EmitScalarRangeCheck(llvm::Value *Value, QualType Ty, -SourceLocation Loc); + /// Returns true if range metadata for the scalar should be dropped. + bool EmitScalarRangeCheck(llvm::Value *Value, QualType Ty, SourceLocation Loc, +Optional BitWidth = None); /// EmitLoadOfScalar - Load a scalar value from an address, taking /// care to appropriately convert from the memory representation to Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -1302,7 +1302,8 @@ } bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty, - SourceLocation Loc) { + SourceLocation Loc, + Optional BitWidth) { bool HasBoolCheck = SanOpts.has(SanitizerKind::Bool); bool HasEnumCheck = SanOpts.has(SanitizerKind::Enum); if (!HasBoolCheck && !HasEnumCheck) @@ -1319,9 +1320,32 @@ if (!getRangeForType(*this, Ty, Min, End, /*StrictEnums=*/true, IsBool)) return true; + --End; + if (BitWidth) { +if (!Min) { + // If End > MaxValueForWidth, t
[PATCH] D30423: [ubsan] Detect UB loads from bitfields
filcab added a comment. LGTM since my issue is only an issue on ObjC platforms and it seems those are the semantics it should have there. Comment at: test/CodeGenObjC/ubsan-bool.m:26 + // OBJC: [[ICMP:%.*]] = icmp ule i8 [[ASHR]], 1, !nosanitize + // OBJC: call void @__ubsan_handle_load_invalid_value + vsk wrote: > filcab wrote: > > jroelofs wrote: > > > vsk wrote: > > > > jroelofs wrote: > > > > > vsk wrote: > > > > > > arphaman wrote: > > > > > > > Is it possible to avoid the check here since the bitfield is just > > > > > > > one bit wide? > > > > > > No, a user could do: > > > > > > > > > > > > ``` > > > > > > struct S1 s; > > > > > > s.b1 = 1; > > > > > > if (s.b1 == 1) // evaluates to false, s.b1 is negative > > > > > > ``` > > > > > > > > > > > > With this patch we get: > > > > > > ``` > > > > > > runtime error: load of value -1, which is not a valid value for > > > > > > type 'BOOL' (aka 'signed char') > > > > > > ``` > > > > > What if BOOL is an `unsigned char`, or a `char` that's not signed? > > > > Good point, we don't need to emit the range check if the bitfield is an > > > > unsigned, 1-bit wide BOOL. Would you be OK with me tackling that in a > > > > follow-up patch? > > > No problem, sounds good to me. > > I don't like generating an error here. > > -1 is a perfectly valid BOOL (signed char) value and it's a perfectly valid > > value to have in a (signed) 1-wide bitfield. > True/false should be the only values loaded from a boolean. Since we made > ubsan stricter about the range of BOOL (r289290), the check has caught a lot > of bugs in our software. Specifically, it's helped root out buggy BOOL > initialization and portability problems (the signedness of BOOL is not > consistent on Apple platforms). There have been no false positives so far. > > Is this an issue you think needs to be addressed in this patch? It looks weird that we would disallow using a 1-bit (signed) bitfield for storing `BOOL`. But since this will only be a problem on obj-c, I don't think it will be a problem in general. If you're saying those are the semantics, then I'm ok with it. P.S: If it documented that the only possible values for `BOOL` are `YES` and `NO` (assuming they are `1` and `0`)? If so, I wonder if it's planned to document that you can't store a `YES` on a `BOOL` bitfield with a width of 1, since it looks like a weird case. https://reviews.llvm.org/D30423 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30685: [include-fixer] Remove line number from Symbol identity
bkramer accepted this revision. bkramer added a comment. lg https://reviews.llvm.org/D30685 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30423: [ubsan] Detect UB loads from bitfields
vsk added a comment. In https://reviews.llvm.org/D30423#695608, @filcab wrote: > LGTM since my issue is only an issue on ObjC platforms and it seems those are > the semantics it should have there. Thanks for the review. > P.S: If it documented that the only possible values for BOOL are YES and NO > (assuming they are 1 and 0)? I think this more or less counts: https://developer.apple.com/reference/objectivec/objective_c_runtime/boolean_values > If so, I wonder if it's planned to document that you can't store a YES on a > BOOL bitfield with a width of 1, since it looks like a weird case. I will ask around. There is a warning about signedness issues here: https://developer.apple.com/reference/objectivec/bool?language=objc https://reviews.llvm.org/D30423 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30739: [OpenMP] "declare simd" for AArch64 Advanced SIMD.
fpetrogalli updated this revision to Diff 91035. fpetrogalli marked an inline comment as done. fpetrogalli added a comment. Changes: - fixed formatting; - added two tests that were missing. https://reviews.llvm.org/D30739 Files: lib/Basic/Targets.cpp lib/CodeGen/CGOpenMPRuntime.cpp test/OpenMP/declare_simd_codegen.cpp Index: test/OpenMP/declare_simd_codegen.cpp === --- test/OpenMP/declare_simd_codegen.cpp +++ test/OpenMP/declare_simd_codegen.cpp @@ -1,15 +1,86 @@ -// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - -femit-all-decls | FileCheck %s +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c++ -emit-llvm %s -o - -femit-all-decls | FileCheck --check-prefix=X86 %s // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls | FileCheck --check-prefix=X86 %s + +// RUN: %clang_cc1 -verify -triple aarch64-linux-gnu -fopenmp -x c++ -emit-llvm %s -o - -femit-all-decls | FileCheck --check-prefix=AARCH64 %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple aarch64-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple aarch64-linux-gnu -include-pch %t -verify %s -emit-llvm -o - -femit-all-decls | FileCheck --check-prefix=AARCH64 %s + // expected-no-diagnostics + +// X86-DAG: define {{.+}}@_Z5add_1Pf( +// X86-DAG: define {{.+}}@_Z1hIiEvPT_S1_S1_S1_( +// X86-DAG: define {{.+}}@_Z1hIfEvPT_S1_S1_S1_( +// X86-DAG: define {{.+}}@_ZN2VV3addEii( +// X86-DAG: define {{.+}}@_ZN2VV6taddpfEPfRS0_( +// X86-DAG: define {{.+}}@_ZN2VV4taddERA_iRi( +// X86-DAG: define {{.+}}@_Z1fRA_i( +// X86-DAG: define {{.+}}@_ZN3TVVILi16EfE6taddpfEPfRS1_( +// X86-DAG: define {{.+}}@_ZN3TVVILi16EfE4taddEi( +// X86-DAG: define {{.+}}@_Z3fooILi64EEvRAT__iRPf( +// X86-DAG: define {{.+}}@_Z3bar2VVPf( +// X86-DAG: define {{.+}}@_Z3baz2VVPi( +// X86-DAG: define {{.+}}@_Z3bay2VVRPd( +// X86-DAG: define {{.+}}@_Z3bax2VVPdi( +// X86-DAG: define {{.+}}@_Z3fooPffi( +// X86-DAG: define {{.+}}@_Z3food( +// X86-NOT: "_ZGV{{.+}}__Z1fRA_i + +// AARCH64-DAG: define {{.+}}@_Z5add_1Pf( +// AARCH64-DAG: define {{.+}}@_Z1hIiEvPT_S1_S1_S1_( +// AARCH64-DAG: define {{.+}}@_Z1hIfEvPT_S1_S1_S1_( +// AARCH64-DAG: define {{.+}}@_ZN2VV3addEii( +// AARCH64-DAG: define {{.+}}@_ZN2VV6taddpfEPfRS0_( +// AARCH64-DAG: define {{.+}}@_ZN2VV4taddERA_iRi( +// AARCH64-DAG: define {{.+}}@_Z1fRA_i( +// AARCH64-DAG: define {{.+}}@_ZN3TVVILi16EfE6taddpfEPfRS1_( +// AARCH64-DAG: define {{.+}}@_ZN3TVVILi16EfE4taddEi( +// AARCH64-DAG: define {{.+}}@_Z3fooILi64EEvRAT__iRPf( +// AARCH64-DAG: define {{.+}}@_Z3bar2VVPf( +// AARCH64-DAG: define {{.+}}@_Z3baz2VVPi( +// AARCH64-DAG: define {{.+}}@_Z3bay2VVRPd( +// AARCH64-DAG: define {{.+}}@_Z3bax2VVPdi( +// AARCH64-DAG: define {{.+}}@_Z3fooPffi( +// AARCH64-DAG: define {{.+}}@_Z3food( +// AARCH64-NOT: "_ZGV{{.+}}__Z1fRA_i + #ifndef HEADER #define HEADER #pragma omp declare simd linear(d : 8) #pragma omp declare simd inbranch simdlen(32) #pragma omp declare simd notinbranch void add_1(float *d) {} +// X86-DAG: "_ZGVbM4l8__Z5add_1Pf" +// X86-DAG: "_ZGVbN4l8__Z5add_1Pf" +// X86-DAG: "_ZGVcM8l8__Z5add_1Pf" +// X86-DAG: "_ZGVcN8l8__Z5add_1Pf" +// X86-DAG: "_ZGVdM8l8__Z5add_1Pf" +// X86-DAG: "_ZGVdN8l8__Z5add_1Pf" +// X86-DAG: "_ZGVeM16l8__Z5add_1Pf" +// X86-DAG: "_ZGVeN16l8__Z5add_1Pf" +// X86-DAG: "_ZGVbM32v__Z5add_1Pf" +// X86-DAG: "_ZGVcM32v__Z5add_1Pf" +// X86-DAG: "_ZGVdM32v__Z5add_1Pf" +// X86-DAG: "_ZGVeM32v__Z5add_1Pf" +// X86-DAG: "_ZGVbN2v__Z5add_1Pf" +// X86-DAG: "_ZGVcN4v__Z5add_1Pf" +// X86-DAG: "_ZGVdN4v__Z5add_1Pf" +// X86-DAG: "_ZGVeN8v__Z5add_1Pf" + +// AARCH64-DAG: "_ZGVnM2l8__Z5add_1Pf" +// AARCH64-DAG: "_ZGVnN2l8__Z5add_1Pf" +// AARCH64-DAG: "_ZGVnM4l8__Z5add_1Pf" +// AARCH64-DAG: "_ZGVnN4l8__Z5add_1Pf" + +// AARCH64-DAG: "_ZGVnM32v__Z5add_1Pf" +// AARCH64-DAG: "_ZGVnM32v__Z5add_1Pf" +// AARCH64-DAG: "_ZGVnM32v__Z5add_1Pf" +// AARCH64-DAG: "_ZGVnM32v__Z5add_1Pf" + +// AARCH64-DAG: "_ZGVnN2v__Z5add_1Pf" + #pragma omp declare simd aligned(hp, hp2) template void h(C *hp, C *hp2, C *hq, C *lin) { @@ -26,6 +97,30 @@ h((float *)hp, (float *)hp2, (float *)hq, (float *)lin); } +// X86-DAG: "_ZGVbM2va16va16vv__Z1hIiEvPT_S1_S1_S1_" +// X86-DAG: "_ZGVbN2va16va16vv__Z1hIiEvPT_S1_S1_S1_" +// X86-DAG: "_ZGVcM4va16va16vv__Z1hIiEvPT_S1_S1_S1_" +// X86-DAG: "_ZGVcN4va16va16vv__Z1hIiEvPT_S1_S1_S1_" +// X86-DAG: "_ZGVdM4va16va16vv__Z1hIiEvPT_S1_S1_S1_" +// X86-DAG: "_ZGVdN4va16va16vv__Z1hIiEvPT_S1_S1_S1_" +// X86-DAG: "_ZGVeM8va16va16vv__Z1hIiEvPT_S1_S1_S1_" +// X86-DAG: "_ZGVeN8va16va16vv__Z1hIiEvPT_S1_S1_S1_" + +// X86-DAG: "_ZGVbM2va16va16vv__Z1hIfEvPT_S1_S1_S1_" +// X86-DAG: "_ZGVbN2va16va1
[PATCH] D30423: [ubsan] Detect UB loads from bitfields
This revision was automatically updated to reflect the committed changes. Closed by commit rL297298: [ubsan] Detect UB loads from bitfields (authored by vedantk). Changed prior to commit: https://reviews.llvm.org/D30423?vs=90869&id=91041#toc Repository: rL LLVM https://reviews.llvm.org/D30423 Files: cfe/trunk/lib/CodeGen/CGAtomic.cpp cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h cfe/trunk/test/CodeGenCXX/ubsan-bitfields.cpp cfe/trunk/test/CodeGenObjC/ubsan-bool.m Index: cfe/trunk/test/CodeGenObjC/ubsan-bool.m === --- cfe/trunk/test/CodeGenObjC/ubsan-bool.m +++ cfe/trunk/test/CodeGenObjC/ubsan-bool.m @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - | FileCheck %s -check-prefixes=SHARED,OBJC -// RUN: %clang_cc1 -x objective-c++ -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - | FileCheck %s -check-prefixes=SHARED,OBJC +// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - -w | FileCheck %s -check-prefixes=SHARED,OBJC +// RUN: %clang_cc1 -x objective-c++ -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - -w | FileCheck %s -check-prefixes=SHARED,OBJC // RUN: %clang_cc1 -x c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - | FileCheck %s -check-prefixes=SHARED,C typedef signed char BOOL; @@ -10,4 +10,57 @@ // C-NOT: call void @__ubsan_handle_load_invalid_value BOOL a = 2; return a + 1; + // SHARED: ret i8 } + +struct S1 { + BOOL b1 : 1; +}; + +// SHARED-LABEL: f2 +BOOL f2(struct S1 *s) { + // OBJC: [[LOAD:%.*]] = load i8, i8* {{.*}} + // OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7 + // OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7 + // OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize + // OBJC: call void @__ubsan_handle_load_invalid_value + + // C-NOT: call void @__ubsan_handle_load_invalid_value + return s->b1; + // SHARED: ret i8 +} + +#ifdef __OBJC__ +@interface I1 { +@public + BOOL b1 : 1; +} +@property (nonatomic) BOOL b1; +@end +@implementation I1 +@synthesize b1; +@end + +// Check the synthesized getter. +// OBJC-LABEL: define internal signext i8 @"\01-[I1 b1]" +// OBJC: [[IVAR:%.*]] = load i64, i64* @"OBJC_IVAR_$_I1.b1" +// OBJC: [[ADDR:%.*]] = getelementptr inbounds i8, i8* {{.*}}, i64 [[IVAR]] +// OBJC: [[LOAD:%.*]] = load i8, i8* {{.*}} +// OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7 +// OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7 +// OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize +// OBJC: call void @__ubsan_handle_load_invalid_value + +// Also check direct accesses to the ivar. +// OBJC-LABEL: f3 +BOOL f3(I1 *i) { + // OBJC: [[LOAD:%.*]] = load i8, i8* {{.*}} + // OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7 + // OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7 + // OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize + // OBJC: call void @__ubsan_handle_load_invalid_value + + return i->b1; + // OBJC: ret i8 +} +#endif /* __OBJC__ */ Index: cfe/trunk/test/CodeGenCXX/ubsan-bitfields.cpp === --- cfe/trunk/test/CodeGenCXX/ubsan-bitfields.cpp +++ cfe/trunk/test/CodeGenCXX/ubsan-bitfields.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=enum | FileCheck %s + +enum E { + a = 1, + b = 2, + c = 3 +}; + +struct S { + E e1 : 10; +}; + +// CHECK-LABEL: define i32 @_Z4loadP1S +E load(S *s) { + // CHECK: [[LOAD:%.*]] = load i16, i16* {{.*}} + // CHECK: [[CLEAR:%.*]] = and i16 [[LOAD]], 1023 + // CHECK: [[CAST:%.*]] = zext i16 [[CLEAR]] to i32 + // CHECK: icmp ule i32 [[CAST]], 3, !nosanitize + // CHECK: call void @__ubsan_handle_load_invalid_value + return s->e1; +} Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -1549,10 +1549,11 @@ return EmitLoadOfGlobalRegLValue(LV); assert(LV.isBitField() && "Unknown LValue type!"); - return EmitLoadOfBitfieldLValue(LV); + return EmitLoadOfBitfieldLValue(LV, Loc); } -RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV) { +RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV, + SourceLocation Loc) { const CGBitFieldInfo &Info = LV.getBitFieldInfo(); // Get the output type. @@ -1577,7 +1578,7 @@ "bf.clear"); } Val = Builder.CreateIntCast(Val, ResLTy, Info.IsSigned, "bf.cast"); - + EmitScalarRangeCheck(Val, LV.getType(), Loc); return RValue::get(Val); } Index: cfe/trunk/lib/CodeGen/CGAtomic.cpp === --- cfe/trunk/lib/CodeGen/CGAtomic.cpp +++ cfe/trunk/lib/CodeGen/CGAtomic.cpp @@ -1181,7 +1181,7 @@ if (LVal.isBitField()) return CGF.EmitLoadOfBitfi
r297298 - [ubsan] Detect UB loads from bitfields
Author: vedantk Date: Wed Mar 8 11:38:57 2017 New Revision: 297298 URL: http://llvm.org/viewvc/llvm-project?rev=297298&view=rev Log: [ubsan] Detect UB loads from bitfields It's possible to load out-of-range values from bitfields backed by a boolean or an enum. Check for UB loads from bitfields. This is the motivating example: struct S { BOOL b : 1; // Signed ObjC BOOL. }; S s; s.b = 1; // This is actually stored as -1. if (s.b == 1) // Evaluates to false, -1 != 1. ... Differential Revision: https://reviews.llvm.org/D30423 Added: cfe/trunk/test/CodeGenCXX/ubsan-bitfields.cpp Modified: cfe/trunk/lib/CodeGen/CGAtomic.cpp cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h cfe/trunk/test/CodeGenObjC/ubsan-bool.m Modified: cfe/trunk/lib/CodeGen/CGAtomic.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGAtomic.cpp?rev=297298&r1=297297&r2=297298&view=diff == --- cfe/trunk/lib/CodeGen/CGAtomic.cpp (original) +++ cfe/trunk/lib/CodeGen/CGAtomic.cpp Wed Mar 8 11:38:57 2017 @@ -1181,7 +1181,7 @@ RValue AtomicInfo::convertAtomicTempToRV if (LVal.isBitField()) return CGF.EmitLoadOfBitfieldLValue( LValue::MakeBitfield(addr, LVal.getBitFieldInfo(), LVal.getType(), - LVal.getAlignmentSource())); + LVal.getAlignmentSource()), loc); if (LVal.isVectorElt()) return CGF.EmitLoadOfLValue( LValue::MakeVectorElt(addr, LVal.getVectorIdx(), LVal.getType(), Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=297298&r1=297297&r2=297298&view=diff == --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Wed Mar 8 11:38:57 2017 @@ -1549,10 +1549,11 @@ RValue CodeGenFunction::EmitLoadOfLValue return EmitLoadOfGlobalRegLValue(LV); assert(LV.isBitField() && "Unknown LValue type!"); - return EmitLoadOfBitfieldLValue(LV); + return EmitLoadOfBitfieldLValue(LV, Loc); } -RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV) { +RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV, + SourceLocation Loc) { const CGBitFieldInfo &Info = LV.getBitFieldInfo(); // Get the output type. @@ -1577,7 +1578,7 @@ RValue CodeGenFunction::EmitLoadOfBitfie "bf.clear"); } Val = Builder.CreateIntCast(Val, ResLTy, Info.IsSigned, "bf.cast"); - + EmitScalarRangeCheck(Val, LV.getType(), Loc); return RValue::get(Val); } Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=297298&r1=297297&r2=297298&view=diff == --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Mar 8 11:38:57 2017 @@ -2943,7 +2943,7 @@ public: /// rvalue, returning the rvalue. RValue EmitLoadOfLValue(LValue V, SourceLocation Loc); RValue EmitLoadOfExtVectorElementLValue(LValue V); - RValue EmitLoadOfBitfieldLValue(LValue LV); + RValue EmitLoadOfBitfieldLValue(LValue LV, SourceLocation Loc); RValue EmitLoadOfGlobalRegLValue(LValue LV); /// EmitStoreThroughLValue - Store the specified rvalue into the specified Added: cfe/trunk/test/CodeGenCXX/ubsan-bitfields.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/ubsan-bitfields.cpp?rev=297298&view=auto == --- cfe/trunk/test/CodeGenCXX/ubsan-bitfields.cpp (added) +++ cfe/trunk/test/CodeGenCXX/ubsan-bitfields.cpp Wed Mar 8 11:38:57 2017 @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=enum | FileCheck %s + +enum E { + a = 1, + b = 2, + c = 3 +}; + +struct S { + E e1 : 10; +}; + +// CHECK-LABEL: define i32 @_Z4loadP1S +E load(S *s) { + // CHECK: [[LOAD:%.*]] = load i16, i16* {{.*}} + // CHECK: [[CLEAR:%.*]] = and i16 [[LOAD]], 1023 + // CHECK: [[CAST:%.*]] = zext i16 [[CLEAR]] to i32 + // CHECK: icmp ule i32 [[CAST]], 3, !nosanitize + // CHECK: call void @__ubsan_handle_load_invalid_value + return s->e1; +} Modified: cfe/trunk/test/CodeGenObjC/ubsan-bool.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/ubsan-bool.m?rev=297298&r1=297297&r2=297298&view=diff == --- cfe/trunk/test/CodeGenObjC/ubsan-bool.m (original) +++ cfe/trunk/test/CodeGenObjC/ubsan-bool.m Wed Mar 8 11:38:57 2017 @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - | FileCheck %s -check
[PATCH] D30720: [include-fixer] Add fuzzy SymbolIndex, where identifier needn't match exactly.
sammccall updated this revision to Diff 91042. sammccall marked 4 inline comments as done. sammccall added a comment. Address review comments. https://reviews.llvm.org/D30720 Files: include-fixer/CMakeLists.txt include-fixer/FuzzySymbolIndex.cpp include-fixer/FuzzySymbolIndex.h include-fixer/SymbolIndexManager.cpp include-fixer/tool/ClangIncludeFixer.cpp test/include-fixer/Inputs/fake_yaml_db.yaml test/include-fixer/yaml_fuzzy.cpp unittests/include-fixer/CMakeLists.txt unittests/include-fixer/FuzzySymbolIndexTests.cpp Index: unittests/include-fixer/FuzzySymbolIndexTests.cpp === --- /dev/null +++ unittests/include-fixer/FuzzySymbolIndexTests.cpp @@ -0,0 +1,61 @@ +//===-- FuzzySymbolIndexTests.cpp - Fuzzy symbol index unit tests -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "FuzzySymbolIndex.h" +#include "gmock/gmock.h" +#include "llvm/Support/Regex.h" +#include "gtest/gtest.h" + +using testing::ElementsAre; +using testing::Not; + +namespace clang { +namespace include_fixer { +namespace { + +TEST(FuzzySymbolIndexTest, Tokenize) { + EXPECT_THAT(FuzzySymbolIndex::tokenize("URLHandlerCallback"), + ElementsAre("url", "handler", "callback")); + EXPECT_THAT(FuzzySymbolIndex::tokenize("snake_case11"), + ElementsAre("snake", "case", "11")); + EXPECT_THAT(FuzzySymbolIndex::tokenize("__$42!!BOB\nbob"), + ElementsAre("42", "bob", "bob")); +} + +MATCHER_P(MatchesSymbol, Identifier, "") { + llvm::Regex Pattern("^" + arg); + std::string err; + if (!Pattern.isValid(err)) { +*result_listener << "invalid regex: " << err; +return false; + } + auto Tokens = FuzzySymbolIndex::tokenize(Identifier); + std::string Target = llvm::join(Tokens.begin(), Tokens.end(), " "); + *result_listener << "matching against '" << Target << "'"; + return llvm::Regex("^" + arg).match(Target); +} + +TEST(FuzzySymbolIndexTest, QueryRegexp) { + auto QueryRegexp = [](const std::string &query) { +return FuzzySymbolIndex::queryRegexp(FuzzySymbolIndex::tokenize(query)); + }; + EXPECT_THAT(QueryRegexp("uhc"), MatchesSymbol("URLHandlerCallback")); + EXPECT_THAT(QueryRegexp("urhaca"), MatchesSymbol("URLHandlerCallback")); + EXPECT_THAT(QueryRegexp("uhcb"), Not(MatchesSymbol("URLHandlerCallback"))) + << "Non-prefix"; + EXPECT_THAT(QueryRegexp("uc"), Not(MatchesSymbol("URLHandlerCallback"))) + << "Skip token"; + + EXPECT_THAT(QueryRegexp("uptr"), MatchesSymbol("unique_ptr")); + EXPECT_THAT(QueryRegexp("UniP"), MatchesSymbol("unique_ptr")); +} + +} // namespace +} // namespace include_fixer +} // namespace clang Index: unittests/include-fixer/CMakeLists.txt === --- unittests/include-fixer/CMakeLists.txt +++ unittests/include-fixer/CMakeLists.txt @@ -13,6 +13,7 @@ add_extra_unittest(IncludeFixerTests IncludeFixerTest.cpp + FuzzySymbolIndexTests.cpp ) target_link_libraries(IncludeFixerTests Index: test/include-fixer/yaml_fuzzy.cpp === --- /dev/null +++ test/include-fixer/yaml_fuzzy.cpp @@ -0,0 +1,9 @@ +// RUN: sed -e 's#//.*$##' %s > %t.cpp +// RUN: clang-include-fixer -db=fuzzyYaml -input=%p/Inputs/fake_yaml_db.yaml %t.cpp -- +// RUN: FileCheck %s -input-file=%t.cpp + +// include-fixer will add the include, but doesn't complete the symbol. +// CHECK: #include "foobar.h" +// CHECK: fba f; + +b::a::fba f; Index: test/include-fixer/Inputs/fake_yaml_db.yaml === --- test/include-fixer/Inputs/fake_yaml_db.yaml +++ test/include-fixer/Inputs/fake_yaml_db.yaml @@ -11,6 +11,18 @@ Seen:1 Used:0 --- +Name: foo_bar +Contexts: + - ContextType: Namespace +ContextName: a + - ContextType: Namespace +ContextName: b +FilePath:foobar.h +LineNumber: 1 +Type:Class +Seen:0 +Used:0 +--- Name: bar Contexts: - ContextType: Namespace Index: include-fixer/tool/ClangIncludeFixer.cpp === --- include-fixer/tool/ClangIncludeFixer.cpp +++ include-fixer/tool/ClangIncludeFixer.cpp @@ -7,6 +7,7 @@ // //===--===// +#include "FuzzySymbolIndex.h" #include "InMemorySymbolIndex.h" #include "IncludeFixer.h" #include "IncludeFixerContext.h" @@ -83,14 +84,16 @@ cl::OptionCategory IncludeFixerCategory("Tool options"); enum DatabaseFormatTy { - fixed, ///< Hard-coded mapping. - yaml, ///< Yaml database created by find-all-symbo
[PATCH] D30720: [include-fixer] Add fuzzy SymbolIndex, where identifier needn't match exactly.
sammccall added a comment. Thanks for the comments! Comment at: include-fixer/SymbolIndexManager.cpp:106 // Match the identifier name without qualifier. - if (Symbol.getName() == Names.back()) { -bool IsMatched = true; hokein wrote: > Just want to verify: this judgement is not needed as it is guaranteed in Line > 96 `DB.get()->search(Names.back())` right? Yes. The existing non-fuzzy implementations all make this guarantee, and we decide that we'll accept results from fuzzy implementations now too. https://reviews.llvm.org/D30720 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30650: [clang-tidy] misc-use-after-move: Fix failing assertion
Eugene.Zelenko added a comment. In https://reviews.llvm.org/D30650#695350, @klimek wrote: > In https://reviews.llvm.org/D30650#693165, @Eugene.Zelenko wrote: > > > I think we should refactor this check as part of Static Analyzer, since > > it's path-sensitive. > > > Are you saying it should be path sensitive? Because currently it's not, right? It handle paths, as far as I could tell from regression test. But will it handle all possible paths? What about path reporting? And this is definitely duplication of Static Analyzer functionality. Repository: rL LLVM https://reviews.llvm.org/D30650 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30748: [Lexer] Finding beginning of token with escaped new line
idlecode created this revision. Lexer::GetBeginningOfToken produced invalid location when backtracking across escaped new lines. This fixes PR26228 https://reviews.llvm.org/D30748 Files: lib/Lex/Lexer.cpp unittests/Lex/LexerTest.cpp Index: unittests/Lex/LexerTest.cpp === --- unittests/Lex/LexerTest.cpp +++ unittests/Lex/LexerTest.cpp @@ -380,4 +380,36 @@ EXPECT_EQ(SourceMgr.getFileIDSize(SourceMgr.getFileID(helper1ArgLoc)), 8U); } +TEST_F(LexerTest, GetBeginningOfTokenWithEscapedNewLine) { + // Each line should have the same length for + // further offset calculation to be more straightforward. + const auto IdentifierLength = 8; + std::string textToLex = +"rabarbar\n" +"foo\\\nbar\n" +"foo\\\rbar\n" +"fo\\\r\nbar\n" +"foo\\\n\rba\n"; + std::vector ExpectedTokens{5, tok::identifier}; + + auto lexedTokens = CheckLex(textToLex, ExpectedTokens); + + for (const auto &tok : lexedTokens) { +auto originalLocation = SourceMgr.getDecomposedLoc(tok.getLocation()); +for (unsigned offset = 0; offset < IdentifierLength; ++offset) { + auto lookupLocation = tok.getLocation().getLocWithOffset(offset); + + auto foundLocation = SourceMgr.getDecomposedExpansionLoc( + Lexer::GetBeginningOfToken( +lookupLocation, +SourceMgr, +LangOpts)); + + // Check that location returned by the GetBeginningOfToken + // is the same as original token location reported by Lexer. + EXPECT_EQ(foundLocation.second, originalLocation.second); +} + } +} + } // anonymous namespace Index: lib/Lex/Lexer.cpp === --- lib/Lex/Lexer.cpp +++ lib/Lex/Lexer.cpp @@ -452,6 +452,13 @@ return false; } +/// \brief Check if new line pointed by Str is escaped. +static bool isNewLineEscaped(const char *BufferStart, const char *Str) { + while (Str > BufferStart && isWhitespace(*Str)) +--Str; + return Str[0] == '\\'; +} + static SourceLocation getBeginningOfFileToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts) { @@ -467,22 +474,23 @@ // Back up from the current location until we hit the beginning of a line // (or the buffer). We'll relex from that point. - const char *BufStart = Buffer.data(); if (LocInfo.second >= Buffer.size()) return Loc; - const char *StrData = BufStart+LocInfo.second; - if (StrData[0] == '\n' || StrData[0] == '\r') -return Loc; + const char *BufStart = Buffer.data(); + const char *StrData = BufStart + LocInfo.second; const char *LexStart = StrData; - while (LexStart != BufStart) { -if (LexStart[0] == '\n' || LexStart[0] == '\r') { - ++LexStart; - break; -} + for (; LexStart != BufStart; --LexStart) { +if (!isVerticalWhitespace(LexStart[0])) + continue; ---LexStart; +if (isNewLineEscaped(BufStart, LexStart)) + continue; + +// LexStart should point at first character of logical line. +++LexStart; +break; } // Create a lexer starting at the beginning of this token. Index: unittests/Lex/LexerTest.cpp === --- unittests/Lex/LexerTest.cpp +++ unittests/Lex/LexerTest.cpp @@ -380,4 +380,36 @@ EXPECT_EQ(SourceMgr.getFileIDSize(SourceMgr.getFileID(helper1ArgLoc)), 8U); } +TEST_F(LexerTest, GetBeginningOfTokenWithEscapedNewLine) { + // Each line should have the same length for + // further offset calculation to be more straightforward. + const auto IdentifierLength = 8; + std::string textToLex = +"rabarbar\n" +"foo\\\nbar\n" +"foo\\\rbar\n" +"fo\\\r\nbar\n" +"foo\\\n\rba\n"; + std::vector ExpectedTokens{5, tok::identifier}; + + auto lexedTokens = CheckLex(textToLex, ExpectedTokens); + + for (const auto &tok : lexedTokens) { +auto originalLocation = SourceMgr.getDecomposedLoc(tok.getLocation()); +for (unsigned offset = 0; offset < IdentifierLength; ++offset) { + auto lookupLocation = tok.getLocation().getLocWithOffset(offset); + + auto foundLocation = SourceMgr.getDecomposedExpansionLoc( + Lexer::GetBeginningOfToken( +lookupLocation, +SourceMgr, +LangOpts)); + + // Check that location returned by the GetBeginningOfToken + // is the same as original token location reported by Lexer. + EXPECT_EQ(foundLocation.second, originalLocation.second); +} + } +} + } // anonymous namespace Index: lib/Lex/Lexer.cpp === --- lib/Lex/Lexer.cpp +++ lib/Lex/Lexer.cpp @@ -452,6 +452,13 @@ return false; } +/// \brief Check if new line pointed by Str is escaped. +static bool isNewLineEscaped(const char *BufferStart, const char *Str) { + while (Str > B
[PATCH] D30551: [AMDGPU] Add builtin functions readlane ds_permute mov_dpp
arsenm accepted this revision. arsenm added a comment. This revision is now accepted and ready to land. LGTM https://reviews.llvm.org/D30551 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r297306 - Fix PR32183 - Wrap GCC exception implementation in missing namespace std
Author: ericwf Date: Wed Mar 8 14:06:01 2017 New Revision: 297306 URL: http://llvm.org/viewvc/llvm-project?rev=297306&view=rev Log: Fix PR32183 - Wrap GCC exception implementation in missing namespace std Modified: libcxx/trunk/src/support/runtime/exception_glibcxx.ipp libcxx/trunk/src/support/runtime/exception_pointer_glibcxx.ipp Modified: libcxx/trunk/src/support/runtime/exception_glibcxx.ipp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/support/runtime/exception_glibcxx.ipp?rev=297306&r1=297305&r2=297306&view=diff == --- libcxx/trunk/src/support/runtime/exception_glibcxx.ipp (original) +++ libcxx/trunk/src/support/runtime/exception_glibcxx.ipp Wed Mar 8 14:06:01 2017 @@ -35,4 +35,4 @@ bad_typeid::bad_typeid() _NOEXCEPT { } -} // namespace +} // namespace std Modified: libcxx/trunk/src/support/runtime/exception_pointer_glibcxx.ipp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/support/runtime/exception_pointer_glibcxx.ipp?rev=297306&r1=297305&r2=297306&view=diff == --- libcxx/trunk/src/support/runtime/exception_pointer_glibcxx.ipp (original) +++ libcxx/trunk/src/support/runtime/exception_pointer_glibcxx.ipp Wed Mar 8 14:06:01 2017 @@ -17,6 +17,8 @@ // stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr) // function. +namespace std { + namespace __exception_ptr { @@ -72,3 +74,5 @@ void rethrow_exception(exception_ptr p) { rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p)); } + +} // namespace std ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30753: Driver/ToolChains: Mips -> MipsLinux
kzhuravl created this revision. Herald added subscribers: mgorny, wdng, sdardis. - Mips is architecture, not a toolchain - Might help eliminate the confusion in the future by not having header files with the same name https://reviews.llvm.org/D30753 Files: lib/Driver/CMakeLists.txt lib/Driver/Driver.cpp lib/Driver/ToolChains/Mips.cpp lib/Driver/ToolChains/Mips.h lib/Driver/ToolChains/MipsLinux.cpp lib/Driver/ToolChains/MipsLinux.h Index: lib/Driver/ToolChains/MipsLinux.h === --- lib/Driver/ToolChains/MipsLinux.h +++ lib/Driver/ToolChains/MipsLinux.h @@ -0,0 +1,62 @@ +//===--- Mips.h - Mips ToolChain Implementations *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MIPS_LINUX_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MIPS_LINUX_H + +#include "Linux.h" +#include "clang/Driver/ToolChain.h" + +namespace clang { +namespace driver { +namespace toolchains { + +class LLVM_LIBRARY_VISIBILITY MipsLLVMToolChain : public Linux { +protected: + Tool *buildLinker() const override; + +public: + MipsLLVMToolChain(const Driver &D, const llvm::Triple &Triple, +const llvm::opt::ArgList &Args); + + void + AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, +llvm::opt::ArgStringList &CC1Args) const override; + + CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; + + std::string findLibCxxIncludePath() const override; + + void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; + + std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, +bool Shared = false) const override; + + std::string computeSysRoot() const override; + + RuntimeLibType GetDefaultRuntimeLibType() const override { +return GCCInstallation.isValid() ? RuntimeLibType::RLT_Libgcc + : RuntimeLibType::RLT_CompilerRT; + } + + const char *getDefaultLinker() const override { +return "lld"; + } + +private: + Multilib SelectedMultilib; + std::string LibSuffix; +}; + +} // end namespace toolchains +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MIPS_LINUX_H Index: lib/Driver/ToolChains/MipsLinux.cpp === --- lib/Driver/ToolChains/MipsLinux.cpp +++ lib/Driver/ToolChains/MipsLinux.cpp @@ -0,0 +1,128 @@ +//===--- Mips.cpp - Mips ToolChain Implementations --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "MipsLinux.h" +#include "Arch/Mips.h" +#include "CommonArgs.h" +#include "clang/Config/config.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/DriverDiagnostic.h" +#include "clang/Driver/Options.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" + +using namespace clang::driver; +using namespace clang::driver::toolchains; +using namespace clang; +using namespace llvm::opt; + +/// Mips Toolchain +MipsLLVMToolChain::MipsLLVMToolChain(const Driver &D, + const llvm::Triple &Triple, + const ArgList &Args) +: Linux(D, Triple, Args) { + // Select the correct multilib according to the given arguments. + DetectedMultilibs Result; + findMIPSMultilibs(D, Triple, "", Args, Result); + Multilibs = Result.Multilibs; + SelectedMultilib = Result.SelectedMultilib; + + // Find out the library suffix based on the ABI. + LibSuffix = tools::mips::getMipsABILibSuffix(Args, Triple); + getFilePaths().clear(); + getFilePaths().push_back(computeSysRoot() + "/usr/lib" + LibSuffix); +} + +void MipsLLVMToolChain::AddClangSystemIncludeArgs( +const ArgList &DriverArgs, ArgStringList &CC1Args) const { + if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) +return; + + const Driver &D = getDriver(); + + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { +SmallString<128> P(D.ResourceDir); +llvm::sys::path::append(P, "include"); +addSystemInclude(DriverArgs, CC1Args, P); + } + + if (DriverArgs.hasArg(options::OPT_nostdlibinc)) +return; + + const auto &Callback = Multilibs.includeDirsCallback(); + if (Callback) { +for (const auto &Path : Callback(SelectedMultilib)) + addExternCSystemIncludeIfExists(Drive
[PATCH] D30753: Driver/ToolChains: Mips -> MipsLinux
dlj accepted this revision. dlj added a comment. This revision is now accepted and ready to land. Looks like a good improvement. Sorry for the confusion. https://reviews.llvm.org/D30753 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D25402: [Driver] Pass -lunwind along with compiler-rt when necessary on Linux
mgorny added a comment. @compnerd, I presume that the option would do nothing when using `-rtlib=libgcc`, correct? Or do we support combining libgcc with another unwinder? https://reviews.llvm.org/D25402 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297307 - [scan-build-py] move argument parsing into separate module
Author: rizsotto Date: Wed Mar 8 15:18:51 2017 New Revision: 297307 URL: http://llvm.org/viewvc/llvm-project?rev=297307&view=rev Log: [scan-build-py] move argument parsing into separate module Differential Revision: https://reviews.llvm.org/D30601 Modified: cfe/trunk/tools/scan-build-py/bin/analyze-build cfe/trunk/tools/scan-build-py/bin/intercept-build cfe/trunk/tools/scan-build-py/bin/scan-build cfe/trunk/tools/scan-build-py/libscanbuild/analyze.py cfe/trunk/tools/scan-build-py/libscanbuild/intercept.py Modified: cfe/trunk/tools/scan-build-py/bin/analyze-build URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build-py/bin/analyze-build?rev=297307&r1=297306&r2=297307&view=diff == --- cfe/trunk/tools/scan-build-py/bin/analyze-build (original) +++ cfe/trunk/tools/scan-build-py/bin/analyze-build Wed Mar 8 15:18:51 2017 @@ -13,5 +13,5 @@ import os.path this_dir = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.dirname(this_dir)) -from libscanbuild.analyze import analyze_build_main -sys.exit(analyze_build_main(this_dir, False)) +from libscanbuild.analyze import analyze_build +sys.exit(analyze_build()) Modified: cfe/trunk/tools/scan-build-py/bin/intercept-build URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build-py/bin/intercept-build?rev=297307&r1=297306&r2=297307&view=diff == --- cfe/trunk/tools/scan-build-py/bin/intercept-build (original) +++ cfe/trunk/tools/scan-build-py/bin/intercept-build Wed Mar 8 15:18:51 2017 @@ -13,5 +13,5 @@ import os.path this_dir = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.dirname(this_dir)) -from libscanbuild.intercept import intercept_build_main -sys.exit(intercept_build_main(this_dir)) +from libscanbuild.intercept import intercept_build +sys.exit(intercept_build()) Modified: cfe/trunk/tools/scan-build-py/bin/scan-build URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build-py/bin/scan-build?rev=297307&r1=297306&r2=297307&view=diff == --- cfe/trunk/tools/scan-build-py/bin/scan-build (original) +++ cfe/trunk/tools/scan-build-py/bin/scan-build Wed Mar 8 15:18:51 2017 @@ -13,5 +13,5 @@ import os.path this_dir = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.dirname(this_dir)) -from libscanbuild.analyze import analyze_build_main -sys.exit(analyze_build_main(this_dir, True)) +from libscanbuild.analyze import scan_build +sys.exit(scan_build()) Modified: cfe/trunk/tools/scan-build-py/libscanbuild/analyze.py URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build-py/libscanbuild/analyze.py?rev=297307&r1=297306&r2=297307&view=diff == --- cfe/trunk/tools/scan-build-py/libscanbuild/analyze.py (original) +++ cfe/trunk/tools/scan-build-py/libscanbuild/analyze.py Wed Mar 8 15:18:51 2017 @@ -11,73 +11,68 @@ To run the static analyzer against a bui -- Analyze: run the analyzer against the captured commands, -- Report:create a cover report from the analyzer outputs. """ -import sys import re import os import os.path import json -import argparse import logging import tempfile import multiprocessing import contextlib import datetime from libscanbuild import command_entry_point, compiler_wrapper, \ -wrapper_environment, reconfigure_logging, run_build, tempdir +wrapper_environment, run_build +from libscanbuild.arguments import parse_args_for_scan_build, \ +parse_args_for_analyze_build from libscanbuild.runner import run from libscanbuild.intercept import capture from libscanbuild.report import document -from libscanbuild.clang import get_checkers from libscanbuild.compilation import split_command -__all__ = ['analyze_build_main', 'analyze_compiler_wrapper'] +__all__ = ['scan_build', 'analyze_build', 'analyze_compiler_wrapper'] COMPILER_WRAPPER_CC = 'analyze-cc' COMPILER_WRAPPER_CXX = 'analyze-c++' @command_entry_point -def analyze_build_main(bin_dir, from_build_command): -""" Entry point for 'analyze-build' and 'scan-build'. """ - -parser = create_parser(from_build_command) -args = parser.parse_args() -validate(parser, args, from_build_command) - -# setup logging -reconfigure_logging(args.verbose) -logging.debug('Raw arguments %s', sys.argv) +def scan_build(): +""" Entry point for scan-build command. """ +args = parse_args_for_scan_build() with report_directory(args.output, args.keep_empty) as target_dir: -if not from_build_command: -# run analyzer only and generate cover report -run_analyzer(args, target_dir) -number_of_bugs = document(args, target_dir, True) -return number_of_bugs if args
r297308 - [scan-build-py] move argument parsing into separate module
Author: rizsotto Date: Wed Mar 8 15:22:32 2017 New Revision: 297308 URL: http://llvm.org/viewvc/llvm-project?rev=297308&view=rev Log: [scan-build-py] move argument parsing into separate module Forgot to add the new module. Added: cfe/trunk/tools/scan-build-py/libscanbuild/arguments.py Added: cfe/trunk/tools/scan-build-py/libscanbuild/arguments.py URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build-py/libscanbuild/arguments.py?rev=297308&view=auto == --- cfe/trunk/tools/scan-build-py/libscanbuild/arguments.py (added) +++ cfe/trunk/tools/scan-build-py/libscanbuild/arguments.py Wed Mar 8 15:22:32 2017 @@ -0,0 +1,430 @@ +# -*- coding: utf-8 -*- +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +""" This module parses and validates arguments for command-line interfaces. + +It uses argparse module to create the command line parser. (This library is +in the standard python library since 3.2 and backported to 2.7, but not +earlier.) + +It also implements basic validation methods, related to the command. +Validations are mostly calling specific help methods, or mangling values. +""" + +import os +import sys +import argparse +import logging +from libscanbuild import reconfigure_logging, tempdir +from libscanbuild.clang import get_checkers + +__all__ = ['parse_args_for_intercept_build', 'parse_args_for_analyze_build', + 'parse_args_for_scan_build'] + + +def parse_args_for_intercept_build(): +""" Parse and validate command-line arguments for intercept-build. """ + +parser = create_intercept_parser() +args = parser.parse_args() + +reconfigure_logging(args.verbose) +logging.debug('Raw arguments %s', sys.argv) + +# short validation logic +if not args.build: +parser.error(message='missing build command') + +logging.debug('Parsed arguments: %s', args) +return args + + +def parse_args_for_analyze_build(): +""" Parse and validate command-line arguments for analyze-build. """ + +from_build_command = False +parser = create_analyze_parser(from_build_command) +args = parser.parse_args() + +reconfigure_logging(args.verbose) +logging.debug('Raw arguments %s', sys.argv) + +normalize_args_for_analyze(args, from_build_command) +validate_args_for_analyze(parser, args, from_build_command) +logging.debug('Parsed arguments: %s', args) +return args + + +def parse_args_for_scan_build(): +""" Parse and validate command-line arguments for scan-build. """ + +from_build_command = True +parser = create_analyze_parser(from_build_command) +args = parser.parse_args() + +reconfigure_logging(args.verbose) +logging.debug('Raw arguments %s', sys.argv) + +normalize_args_for_analyze(args, from_build_command) +validate_args_for_analyze(parser, args, from_build_command) +logging.debug('Parsed arguments: %s', args) +return args + + +def normalize_args_for_analyze(args, from_build_command): +""" Normalize parsed arguments for analyze-build and scan-build. + +:param args: Parsed argument object. (Will be mutated.) +:param from_build_command: Boolean value tells is the command suppose +to run the analyzer against a build command or a compilation db. """ + +# make plugins always a list. (it might be None when not specified.) +if args.plugins is None: +args.plugins = [] + +# make exclude directory list unique and absolute. +uniq_excludes = set(os.path.abspath(entry) for entry in args.excludes) +args.excludes = list(uniq_excludes) + +# because shared codes for all tools, some common used methods are +# expecting some argument to be present. so, instead of query the args +# object about the presence of the flag, we fake it here. to make those +# methods more readable. (it's an arguable choice, took it only for those +# which have good default value.) +if from_build_command: +# add cdb parameter invisibly to make report module working. +args.cdb = 'compile_commands.json' + + +def validate_args_for_analyze(parser, args, from_build_command): +""" Command line parsing is done by the argparse module, but semantic +validation still needs to be done. This method is doing it for +analyze-build and scan-build commands. + +:param parser: The command line parser object. +:param args: Parsed argument object. +:param from_build_command: Boolean value tells is the command suppose +to run the analyzer against a build command or a compilation db. +:return: No return value, but this call might throw when validation +fails. """ + +if args.help_checkers_verbose: +print_checkers(get_checkers(args.clang, args.plugins)) +parser.exit(status=0) +elif args.help_checkers: +print_active
[PATCH] D26316: [coroutines] Build and pass coroutine_handle to await_suspend.
EricWF added a comment. This LGTM, but I don't know enough Clang to be 100% on it. Perhaps somebody else could give it a quick second look? Comment at: lib/Sema/SemaCoroutine.cpp:157 + if (S.RequireCompleteType(Loc, CoroHandleType, +diag::err_coroutine_traits_missing_specialization)) +return QualType(); Should this diagnostic be renamed since it's general to both `coroutine_traits` and `coroutine_handle`? Comment at: test/SemaCXX/coroutines.cpp:540 + //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}} + //expected-note@+1 {{function is a coroutine due to use of 'co_return' here}} + co_return; Nit, put the `// expected-note` directly on the `co_return` line. https://reviews.llvm.org/D26316 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D22862: [analyzer] Fix for PR15623: eliminate unwanted ProgramState checker data propagation.
zaks.anna accepted this revision. zaks.anna added a comment. This revision is now accepted and ready to land. Thi has been committed in r290505. https://reviews.llvm.org/D22862 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D26316: [coroutines] Build and pass coroutine_handle to await_suspend.
EricWF accepted this revision. EricWF added a comment. This revision is now accepted and ready to land. On second thought if @rsmith already reviewed most of this offline then I feel comfortable giving it the thumbs up. https://reviews.llvm.org/D26316 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r297311 - [clang-tidy] readability-function-size: remove default param count threshold
Author: alexfh Date: Wed Mar 8 16:19:55 2017 New Revision: 297311 URL: http://llvm.org/viewvc/llvm-project?rev=297311&view=rev Log: [clang-tidy] readability-function-size: remove default param count threshold Modified: clang-tools-extra/trunk/clang-tidy/readability/FunctionSizeCheck.cpp Modified: clang-tools-extra/trunk/clang-tidy/readability/FunctionSizeCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/FunctionSizeCheck.cpp?rev=297311&r1=297310&r2=297311&view=diff == --- clang-tools-extra/trunk/clang-tidy/readability/FunctionSizeCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/readability/FunctionSizeCheck.cpp Wed Mar 8 16:19:55 2017 @@ -73,7 +73,7 @@ FunctionSizeCheck::FunctionSizeCheck(Str LineThreshold(Options.get("LineThreshold", -1U)), StatementThreshold(Options.get("StatementThreshold", 800U)), BranchThreshold(Options.get("BranchThreshold", -1U)), - ParameterThreshold(Options.get("ParameterThreshold", 6)) {} + ParameterThreshold(Options.get("ParameterThreshold", -1U)) {} void FunctionSizeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "LineThreshold", LineThreshold); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297312 - Driver/ToolChains: Mips -> MipsLinux
Author: kzhuravl Date: Wed Mar 8 16:36:04 2017 New Revision: 297312 URL: http://llvm.org/viewvc/llvm-project?rev=297312&view=rev Log: Driver/ToolChains: Mips -> MipsLinux - Mips is architecture, not a toolchain - Might help eliminate the confusion in the future by not having header files with the same name Differential Revision: https://reviews.llvm.org/D30753 Added: cfe/trunk/lib/Driver/ToolChains/MipsLinux.cpp cfe/trunk/lib/Driver/ToolChains/MipsLinux.h Removed: cfe/trunk/lib/Driver/ToolChains/Mips.cpp cfe/trunk/lib/Driver/ToolChains/Mips.h Modified: cfe/trunk/lib/Driver/CMakeLists.txt cfe/trunk/lib/Driver/Driver.cpp Modified: cfe/trunk/lib/Driver/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/CMakeLists.txt?rev=297312&r1=297311&r2=297312&view=diff == --- cfe/trunk/lib/Driver/CMakeLists.txt (original) +++ cfe/trunk/lib/Driver/CMakeLists.txt Wed Mar 8 16:36:04 2017 @@ -44,7 +44,7 @@ add_clang_library(clangDriver ToolChains/Haiku.cpp ToolChains/Hexagon.cpp ToolChains/Linux.cpp - ToolChains/Mips.cpp + ToolChains/MipsLinux.cpp ToolChains/MinGW.cpp ToolChains/Minix.cpp ToolChains/MSVC.cpp Modified: cfe/trunk/lib/Driver/Driver.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=297312&r1=297311&r2=297312&view=diff == --- cfe/trunk/lib/Driver/Driver.cpp (original) +++ cfe/trunk/lib/Driver/Driver.cpp Wed Mar 8 16:36:04 2017 @@ -28,7 +28,7 @@ #include "ToolChains/Linux.h" #include "ToolChains/MinGW.h" #include "ToolChains/Minix.h" -#include "ToolChains/Mips.h" +#include "ToolChains/MipsLinux.h" #include "ToolChains/MSVC.h" #include "ToolChains/Myriad.h" #include "ToolChains/NaCl.h" Removed: cfe/trunk/lib/Driver/ToolChains/Mips.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Mips.cpp?rev=297311&view=auto == --- cfe/trunk/lib/Driver/ToolChains/Mips.cpp (original) +++ cfe/trunk/lib/Driver/ToolChains/Mips.cpp (removed) @@ -1,128 +0,0 @@ -//===--- Mips.cpp - Mips ToolChain Implementations --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===--===// - -#include "Mips.h" -#include "Arch/Mips.h" -#include "CommonArgs.h" -#include "clang/Config/config.h" -#include "clang/Driver/Driver.h" -#include "clang/Driver/DriverDiagnostic.h" -#include "clang/Driver/Options.h" -#include "llvm/Option/ArgList.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" - -using namespace clang::driver; -using namespace clang::driver::toolchains; -using namespace clang; -using namespace llvm::opt; - -/// Mips Toolchain -MipsLLVMToolChain::MipsLLVMToolChain(const Driver &D, - const llvm::Triple &Triple, - const ArgList &Args) -: Linux(D, Triple, Args) { - // Select the correct multilib according to the given arguments. - DetectedMultilibs Result; - findMIPSMultilibs(D, Triple, "", Args, Result); - Multilibs = Result.Multilibs; - SelectedMultilib = Result.SelectedMultilib; - - // Find out the library suffix based on the ABI. - LibSuffix = tools::mips::getMipsABILibSuffix(Args, Triple); - getFilePaths().clear(); - getFilePaths().push_back(computeSysRoot() + "/usr/lib" + LibSuffix); -} - -void MipsLLVMToolChain::AddClangSystemIncludeArgs( -const ArgList &DriverArgs, ArgStringList &CC1Args) const { - if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) -return; - - const Driver &D = getDriver(); - - if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { -SmallString<128> P(D.ResourceDir); -llvm::sys::path::append(P, "include"); -addSystemInclude(DriverArgs, CC1Args, P); - } - - if (DriverArgs.hasArg(options::OPT_nostdlibinc)) -return; - - const auto &Callback = Multilibs.includeDirsCallback(); - if (Callback) { -for (const auto &Path : Callback(SelectedMultilib)) - addExternCSystemIncludeIfExists(DriverArgs, CC1Args, - D.getInstalledDir() + Path); - } -} - -Tool *MipsLLVMToolChain::buildLinker() const { - return new tools::gnutools::Linker(*this); -} - -std::string MipsLLVMToolChain::computeSysRoot() const { - if (!getDriver().SysRoot.empty()) -return getDriver().SysRoot + SelectedMultilib.osSuffix(); - - const std::string InstalledDir(getDriver().getInstalledDir()); - std::string SysRootPath = - InstalledDir + "/../sysroot" + SelectedMultilib.osSuffix(); - if (llvm::sys::fs::exists(SysRootPath)) -return SysRootPath; - - return std::stri
[PATCH] D30753: Driver/ToolChains: Mips -> MipsLinux
This revision was automatically updated to reflect the committed changes. Closed by commit rL297312: Driver/ToolChains: Mips -> MipsLinux (authored by kzhuravl). Changed prior to commit: https://reviews.llvm.org/D30753?vs=91060&id=91078#toc Repository: rL LLVM https://reviews.llvm.org/D30753 Files: cfe/trunk/lib/Driver/CMakeLists.txt cfe/trunk/lib/Driver/Driver.cpp cfe/trunk/lib/Driver/ToolChains/Mips.cpp cfe/trunk/lib/Driver/ToolChains/Mips.h cfe/trunk/lib/Driver/ToolChains/MipsLinux.cpp cfe/trunk/lib/Driver/ToolChains/MipsLinux.h Index: cfe/trunk/lib/Driver/ToolChains/MipsLinux.cpp === --- cfe/trunk/lib/Driver/ToolChains/MipsLinux.cpp +++ cfe/trunk/lib/Driver/ToolChains/MipsLinux.cpp @@ -0,0 +1,128 @@ +//===--- Mips.cpp - Mips ToolChain Implementations --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "MipsLinux.h" +#include "Arch/Mips.h" +#include "CommonArgs.h" +#include "clang/Config/config.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/DriverDiagnostic.h" +#include "clang/Driver/Options.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" + +using namespace clang::driver; +using namespace clang::driver::toolchains; +using namespace clang; +using namespace llvm::opt; + +/// Mips Toolchain +MipsLLVMToolChain::MipsLLVMToolChain(const Driver &D, + const llvm::Triple &Triple, + const ArgList &Args) +: Linux(D, Triple, Args) { + // Select the correct multilib according to the given arguments. + DetectedMultilibs Result; + findMIPSMultilibs(D, Triple, "", Args, Result); + Multilibs = Result.Multilibs; + SelectedMultilib = Result.SelectedMultilib; + + // Find out the library suffix based on the ABI. + LibSuffix = tools::mips::getMipsABILibSuffix(Args, Triple); + getFilePaths().clear(); + getFilePaths().push_back(computeSysRoot() + "/usr/lib" + LibSuffix); +} + +void MipsLLVMToolChain::AddClangSystemIncludeArgs( +const ArgList &DriverArgs, ArgStringList &CC1Args) const { + if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) +return; + + const Driver &D = getDriver(); + + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { +SmallString<128> P(D.ResourceDir); +llvm::sys::path::append(P, "include"); +addSystemInclude(DriverArgs, CC1Args, P); + } + + if (DriverArgs.hasArg(options::OPT_nostdlibinc)) +return; + + const auto &Callback = Multilibs.includeDirsCallback(); + if (Callback) { +for (const auto &Path : Callback(SelectedMultilib)) + addExternCSystemIncludeIfExists(DriverArgs, CC1Args, + D.getInstalledDir() + Path); + } +} + +Tool *MipsLLVMToolChain::buildLinker() const { + return new tools::gnutools::Linker(*this); +} + +std::string MipsLLVMToolChain::computeSysRoot() const { + if (!getDriver().SysRoot.empty()) +return getDriver().SysRoot + SelectedMultilib.osSuffix(); + + const std::string InstalledDir(getDriver().getInstalledDir()); + std::string SysRootPath = + InstalledDir + "/../sysroot" + SelectedMultilib.osSuffix(); + if (llvm::sys::fs::exists(SysRootPath)) +return SysRootPath; + + return std::string(); +} + +ToolChain::CXXStdlibType +MipsLLVMToolChain::GetCXXStdlibType(const ArgList &Args) const { + Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); + if (A) { +StringRef Value = A->getValue(); +if (Value != "libc++") + getDriver().Diag(clang::diag::err_drv_invalid_stdlib_name) + << A->getAsString(Args); + } + + return ToolChain::CST_Libcxx; +} + +std::string MipsLLVMToolChain::findLibCxxIncludePath() const { + if (const auto &Callback = Multilibs.includeDirsCallback()) { +for (std::string Path : Callback(SelectedMultilib)) { + Path = getDriver().getInstalledDir() + Path + "/c++/v1"; + if (llvm::sys::fs::exists(Path)) { +return Path; + } +} + } + return ""; +} + +void MipsLLVMToolChain::AddCXXStdlibLibArgs(const ArgList &Args, +ArgStringList &CmdArgs) const { + assert((GetCXXStdlibType(Args) == ToolChain::CST_Libcxx) && + "Only -lc++ (aka libxx) is suported in this toolchain."); + + CmdArgs.push_back("-lc++"); + CmdArgs.push_back("-lc++abi"); + CmdArgs.push_back("-lunwind"); +} + +std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args, + StringRef Component, + bool Shared) const { + SmallString<128> Path(getDriver().ResourceDir); + llvm::sys::path::append(Path, SelectedMultilib.osSuffix(), "lib" +
[PATCH] D30740: Remove a useless subsitution in doxygen2rst which was incorrectly replacing * by \*
djasper accepted this revision. djasper added a comment. This revision is now accepted and ready to land. Looks good. https://reviews.llvm.org/D30740 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297316 - Take into account C++17's noexcept function types during merging -- it should
Author: rsmith Date: Wed Mar 8 17:00:26 2017 New Revision: 297316 URL: http://llvm.org/viewvc/llvm-project?rev=297316&view=rev Log: Take into account C++17's noexcept function types during merging -- it should be possible to merge a declaration with an unresolved function type against one with a resolved function type. Added: cfe/trunk/test/Modules/Inputs/cxx17/ cfe/trunk/test/Modules/Inputs/cxx17/decls.h cfe/trunk/test/Modules/Inputs/cxx17/module.modulemap cfe/trunk/test/Modules/cxx17.cpp Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=297316&r1=297315&r2=297316&view=diff == --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Mar 8 17:00:26 2017 @@ -2758,9 +2758,23 @@ static bool isSameEntity(NamedDecl *X, N CtorY->getInheritedConstructor().getConstructor())) return false; } +ASTContext &C = FuncX->getASTContext(); +if (!C.hasSameType(FuncX->getType(), FuncY->getType())) { + // We can get functions with different types on the redecl chain in C++17 + // if they have differing exception specifications and at least one of + // the excpetion specs is unresolved. + // FIXME: Do we need to check for C++14 deduced return types here too? + auto *XFPT = FuncX->getType()->getAs(); + auto *YFPT = FuncY->getType()->getAs(); + if (C.getLangOpts().CPlusPlus1z && XFPT && YFPT && + (isUnresolvedExceptionSpec(XFPT->getExceptionSpecType()) || + isUnresolvedExceptionSpec(YFPT->getExceptionSpecType())) && + C.hasSameFunctionTypeIgnoringExceptionSpec(FuncX->getType(), + FuncY->getType())) +return true; + return false; +} return FuncX->getLinkageInternal() == FuncY->getLinkageInternal() && - FuncX->getASTContext().hasSameType(FuncX->getType(), - FuncY->getType()) && hasSameOverloadableAttrs(FuncX, FuncY); } Added: cfe/trunk/test/Modules/Inputs/cxx17/decls.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx17/decls.h?rev=297316&view=auto == --- cfe/trunk/test/Modules/Inputs/cxx17/decls.h (added) +++ cfe/trunk/test/Modules/Inputs/cxx17/decls.h Wed Mar 8 17:00:26 2017 @@ -0,0 +1,3 @@ +struct MergeExceptionSpec { + ~MergeExceptionSpec(); // unevaluated exception spec +}; Added: cfe/trunk/test/Modules/Inputs/cxx17/module.modulemap URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx17/module.modulemap?rev=297316&view=auto == --- cfe/trunk/test/Modules/Inputs/cxx17/module.modulemap (added) +++ cfe/trunk/test/Modules/Inputs/cxx17/module.modulemap Wed Mar 8 17:00:26 2017 @@ -0,0 +1 @@ +module Decls { header "decls.h" } Added: cfe/trunk/test/Modules/cxx17.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/cxx17.cpp?rev=297316&view=auto == --- cfe/trunk/test/Modules/cxx17.cpp (added) +++ cfe/trunk/test/Modules/cxx17.cpp Wed Mar 8 17:00:26 2017 @@ -0,0 +1,11 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -x c++ -std=c++1z -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/cxx17 %s -verify -fno-modules-error-recovery + +// expected-no-diagnostics +struct MergeExceptionSpec { + ~MergeExceptionSpec(); +} mergeExceptionSpec; // trigger evaluation of exception spec + +#include "decls.h" + +MergeExceptionSpec mergeExceptionSpec2; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30762: [ubsan] Add a nullability sanitizer
vsk created this revision. Teach UBSan how to detect violations of the _Nonnull annotation when passing arguments to callees, in assignments, and in return stmts. Because _Nonnull does not affect IRGen, the new checks are disabled by default. The new driver flags are: -fsanitize=nullability-arg (_Nonnull violation in call) -fsanitize=nullability-assign (_Nonnull violation in assignment) -fsanitize=nullability-return (_Nonnull violation in return stmt) -fsanitize=nullability (all of the above) This patch builds on top of UBSan's existing support for detecting violations of the nonnull attributes ('nonnull' and 'returns_nonnull'). I am reusing the compiler-rt support for the existing checks for now. I have FIXME's for this, and plan on handling them in a follow-up. One point of note is that the nullability-return check is only allowed to kick in if all arguments to the function satisfy their nullability preconditions. This makes it necessary to emit some null checks in the function body itself. Testing: check-clang and check-ubsan. I also built some Apple ObjC frameworks with an asserts-enabled compiler, and verified that we get valid reports. https://reviews.llvm.org/D30762 Files: docs/UndefinedBehaviorSanitizer.rst include/clang/Basic/Sanitizers.def lib/CodeGen/CGCall.cpp lib/CodeGen/CGDecl.cpp lib/CodeGen/CGExprScalar.cpp lib/CodeGen/CodeGenFunction.cpp lib/CodeGen/CodeGenFunction.h lib/Driver/SanitizerArgs.cpp lib/Driver/ToolChain.cpp test/CodeGenObjC/ubsan-null-retval.m test/CodeGenObjC/ubsan-nullability.m Index: test/CodeGenObjC/ubsan-nullability.m === --- /dev/null +++ test/CodeGenObjC/ubsan-nullability.m @@ -0,0 +1,182 @@ +// REQUIRES: asserts +// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=nullability-arg,nullability-assign,nullability-return -w %s -o - | FileCheck %s + +// CHECK: [[NONNULL_RV_LOC1:@.*]] = private unnamed_addr global {{.*}} i32 109, i32 1 {{.*}} i32 100, i32 6 +// CHECK: [[NONNULL_ARG_LOC:@.*]] = private unnamed_addr global {{.*}} i32 204, i32 15 {{.*}} i32 190, i32 23 +// CHECK: [[NONNULL_ASSIGN1_LOC:@.*]] = private unnamed_addr global {{.*}} i32 305, i32 9 +// CHECK: [[NONNULL_ASSIGN2_LOC:@.*]] = private unnamed_addr global {{.*}} i32 405, i32 10 +// CHECK: [[NONNULL_ASSIGN3_LOC:@.*]] = private unnamed_addr global {{.*}} i32 505, i32 10 +// CHECK: [[NONNULL_INIT1_LOC:@.*]] = private unnamed_addr global {{.*}} i32 604, i32 25 +// CHECK: [[NONNULL_INIT2_LOC1:@.*]] = private unnamed_addr global {{.*}} i32 707, i32 26 +// CHECK: [[NONNULL_INIT2_LOC2:@.*]] = private unnamed_addr global {{.*}} i32 707, i32 29 +// CHECK: [[NONNULL_RV_LOC2:@.*]] = private unnamed_addr global {{.*}} i32 817, i32 1 {{.*}} i32 800, i32 6 + +#define NULL ((void *)0) + +// CHECK-LABEL: define i32* @nonnull_retval1 +#line 100 +int *_Nonnull nonnull_retval1(int *p) { + // CHECK: br i1 true, label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize + // CHECK: [[NULL]]: + // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize + // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize + // CHECK: call void @__ubsan_handle_nonnull_return{{.*}}[[NONNULL_RV_LOC1]] + return p; + // CHECK: [[NONULL]]: + // CHECK: ret i32* +} + +#line 190 +void nonnull_arg(int *_Nonnull p) {} + +// CHECK-LABEL: define void @call_func_with_nonnull_arg +#line 200 +void call_func_with_nonnull_arg(int *_Nonnull p) { + // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize + // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize + // CHECK: call void @__ubsan_handle_nonnull_arg{{.*}}[[NONNULL_ARG_LOC]] + nonnull_arg(p); +} + +// CHECK-LABEL: define void @nonnull_assign1 +#line 300 +void nonnull_assign1(int *p) { + // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize + // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize + // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN1_LOC]] + int *_Nonnull local; + local = p; +} + +// CHECK-LABEL: define void @nonnull_assign2 +#line 400 +void nonnull_assign2(int *p) { + // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize + // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize + // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN2_LOC]] + int *_Nonnull arr[1]; + arr[0] = p; +} + +struct S1 { + int *_Nonnull mptr; +}; + +// CHECK-LABEL: define void @nonnull_assign3 +#line 500 +void nonnull_assign3(int *p) { + // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize + // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize + // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN3_LOC]] + struct S1 s; + s.mptr = p; +} + +// CHECK-LABEL: define void @nonnull_init1 +#line 600 +void nonnull_init1(int *p) { + // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize + // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize + // CHECK: call void @__ubs
[PATCH] D26316: [coroutines] Build and pass coroutine_handle to await_suspend.
EricWF added a comment. @GorNishanov You forgot to update `test/SemaCXX/coreturn.cpp`. https://reviews.llvm.org/D26316 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30765: Reexport operator new / delete from libc++abi
mehdi_amini created this revision. Both libc++ and libc++abi export a weak definition of operator new/delete. On Darwin, this can often cause dirty __DATA in the shared cache when having to switch from one to the other. Instead, libc++ should reexport libc++abi's implementation of these symbols. Patch by: Ted Kremenek https://reviews.llvm.org/D30765 Files: lib/libc++abi2.exp Index: lib/libc++abi2.exp === --- lib/libc++abi2.exp +++ lib/libc++abi2.exp @@ -209,14 +209,14 @@ __ZNSt20bad_array_new_lengthD0Ev __ZNSt20bad_array_new_lengthD2Ev __ZSt10unexpectedv -# __ZdaPv -# __ZdlPv -# __ZdlPvRKSt9nothrow_t -# __Znam -# __ZdaPvRKSt9nothrow_t -# __Znwm -# __ZnwmRKSt9nothrow_t -# __ZnamRKSt9nothrow_t +__ZdaPv +__ZdlPv +__ZdlPvRKSt9nothrow_t +__Znam +__ZdaPvRKSt9nothrow_t +__Znwm +__ZnwmRKSt9nothrow_t +__ZnamRKSt9nothrow_t __ZTISt10bad_typeid __ZTISt8bad_cast ___cxa_bad_typeid Index: lib/libc++abi2.exp === --- lib/libc++abi2.exp +++ lib/libc++abi2.exp @@ -209,14 +209,14 @@ __ZNSt20bad_array_new_lengthD0Ev __ZNSt20bad_array_new_lengthD2Ev __ZSt10unexpectedv -# __ZdaPv -# __ZdlPv -# __ZdlPvRKSt9nothrow_t -# __Znam -# __ZdaPvRKSt9nothrow_t -# __Znwm -# __ZnwmRKSt9nothrow_t -# __ZnamRKSt9nothrow_t +__ZdaPv +__ZdlPv +__ZdlPvRKSt9nothrow_t +__Znam +__ZdaPvRKSt9nothrow_t +__Znwm +__ZnwmRKSt9nothrow_t +__ZnamRKSt9nothrow_t __ZTISt10bad_typeid __ZTISt8bad_cast ___cxa_bad_typeid ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30765: Reexport operator new / delete from libc++abi
mehdi_amini added a comment. Note: this is already shipping like this for ~2 years in our OSes. https://reviews.llvm.org/D30765 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30764: Disable unsigned integer sanitizer for basic_string::replace()
srhines added a comment. You probably want to remove the Change-Id section above in your description (or at least drop that when you finally submit this to libc++). https://reviews.llvm.org/D30764 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30766: Add support for attribute "enum_extensibility"
ahatanak created this revision. This patch adds support for a new attribute that will be used to distinguish between extensible and inextensible enums. The attribute was discussed on cfe-dev a few weeks ago and I've made a few modifications to the original proposal based on the feedback I received. http://lists.llvm.org/pipermail/cfe-dev/2017-February/052748.html In this patch, I didn't include the command line option for setting the default enum style for unannotated enums since I wasn't sure it's something we absolutely need. If it turns the warnings are too noisy, I'll consider adding a command line option for silencing the false positive warnings in a follow-up patch. https://reviews.llvm.org/D30766 Files: include/clang/AST/Decl.h include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/AST/Decl.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclAttr.cpp lib/Sema/SemaStmt.cpp test/Sema/enum-attr.c test/SemaCXX/attr-flag-enum-reject.cpp test/SemaCXX/enum-attr.cpp Index: test/SemaCXX/enum-attr.cpp === --- /dev/null +++ test/SemaCXX/enum-attr.cpp @@ -0,0 +1,108 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wassign-enum -Wswitch-enum -Wcovered-switch-default -std=c++11 %s + +enum Enum { + A0 = 1, A1 = 10 +}; + +enum __attribute__((enum_extensibility(closed))) EnumClosed { + B0 = 1, B1 = 10 +}; + +enum __attribute__((enum_extensibility(open))) EnumOpen { + C0 = 1, C1 = 10 +}; + +enum __attribute__((flag_enum)) EnumFlag { + D0 = 1, D1 = 8 +}; + +enum __attribute__((flag_enum,enum_extensibility(closed))) EnumFlagClosed { + E0 = 1, E1 = 8 +}; + +enum __attribute__((flag_enum,enum_extensibility(open))) EnumFlagOpen { + F0 = 1, F1 = 8 +}; + +void test() { + enum Enum t0; + + switch (t0) { // expected-warning{{enumeration value 'A1' not handled in switch}} + case A0: break; + case 16: break; // expected-warning{{case value not in enumerated type}} + } + + switch (t0) { + case A0: break; + case A1: break; + default: break; // expected-warning{{default label in switch which covers all enumeration}} + } + + enum EnumClosed t1; + + switch (t1) { // expected-warning{{enumeration value 'B1' not handled in switch}} + case B0: break; + case 16: break; // expected-warning{{case value not in enumerated type}} + } + + switch (t1) { + case B0: break; + case B1: break; + default: break; // expected-warning{{default label in switch which covers all enumeration}} + } + + enum EnumOpen t2; + + switch (t2) { // expected-warning{{enumeration value 'C1' not handled in switch}} + case C0: break; + case 16: break; + } + + switch (t2) { + case C0: break; + case C1: break; + default: break; + } + + enum EnumFlag t3; + + switch (t3) { // expected-warning{{enumeration value 'D1' not handled in switch}} + case D0: break; + case 9: break; + case 16: break; // expected-warning{{case value not in enumerated type}} + } + + switch (t3) { + case D0: break; + case D1: break; + default: break; + } + + enum EnumFlagClosed t4; + + switch (t4) { // expected-warning{{enumeration value 'E1' not handled in switch}} + case E0: break; + case 9: break; + case 16: break; // expected-warning{{case value not in enumerated type}} + } + + switch (t4) { + case E0: break; + case E1: break; + default: break; + } + + enum EnumFlagOpen t5; + + switch (t5) { // expected-warning{{enumeration value 'F1' not handled in switch}} + case F0: break; + case 9: break; + case 16: break; + } + + switch (t5) { + case F0: break; + case F1: break; + default: break; + } +} Index: test/SemaCXX/attr-flag-enum-reject.cpp === --- test/SemaCXX/attr-flag-enum-reject.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %clang_cc1 -verify -fsyntax-only -x c++ -Wassign-enum %s - -enum __attribute__((flag_enum)) flag { // expected-warning {{ignored}} -}; Index: test/Sema/enum-attr.c === --- /dev/null +++ test/Sema/enum-attr.c @@ -0,0 +1,118 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wassign-enum -Wswitch-enum -Wcovered-switch-default %s + +enum Enum { + A0 = 1, A1 = 10 +}; + +enum __attribute__((enum_extensibility(closed))) EnumClosed { + B0 = 1, B1 = 10 +}; + +enum __attribute__((enum_extensibility(open))) EnumOpen { + C0 = 1, C1 = 10 +}; + +enum __attribute__((flag_enum)) EnumFlag { + D0 = 1, D1 = 8 +}; + +enum __attribute__((flag_enum,enum_extensibility(closed))) EnumFlagClosed { + E0 = 1, E1 = 8 +}; + +enum __attribute__((flag_enum,enum_extensibility(open))) EnumFlagOpen { + F0 = 1, F1 = 8 +}; + +enum __attribute__((enum_extensibility(arg1))) EnumInvalidArg { // expected-warning{{'enum_extensibility' attribute argument not supported: 'arg1'}} + G +}; + +void test() { + enum Enum t0 = 100; // expected-warning{{integer constant not in range of enumerated type}} + t0 = 1; + + switch (t0) { // expec
r297321 - [DebugInfo] Add address space when creating DIDerivedTypes
Author: kzhuravl Date: Wed Mar 8 17:56:48 2017 New Revision: 297321 URL: http://llvm.org/viewvc/llvm-project?rev=297321&view=rev Log: [DebugInfo] Add address space when creating DIDerivedTypes Differential Revision: https://reviews.llvm.org/D29671 Added: cfe/trunk/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl Modified: cfe/trunk/include/clang/Basic/TargetInfo.h cfe/trunk/lib/Basic/Targets.cpp cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Modified: cfe/trunk/include/clang/Basic/TargetInfo.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TargetInfo.h?rev=297321&r1=297320&r2=297321&view=diff == --- cfe/trunk/include/clang/Basic/TargetInfo.h (original) +++ cfe/trunk/include/clang/Basic/TargetInfo.h Wed Mar 8 17:56:48 2017 @@ -1032,6 +1032,21 @@ public: return LangAS::opencl_global; } + /// \returns Target specific vtbl ptr address space. + virtual unsigned getVtblPtrAddressSpace() const { +return 0; + } + + /// \returns If a target requires an address within a target specific address + /// space \p AddressSpace to be converted in order to be used, then return the + /// corresponding target specific DWARF address space. + /// + /// \returns Otherwise return None and no conversion will be emitted in the + /// DWARF. + virtual Optional getDWARFAddressSpace(unsigned AddressSpace) const { +return None; + } + /// \brief Check the target is valid after it is fully initialized. virtual bool validateTarget(DiagnosticsEngine &Diags) const { return true; Modified: cfe/trunk/lib/Basic/Targets.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=297321&r1=297320&r2=297321&view=diff == --- cfe/trunk/lib/Basic/Targets.cpp (original) +++ cfe/trunk/lib/Basic/Targets.cpp Wed Mar 8 17:56:48 2017 @@ -2258,6 +2258,32 @@ public: return LangAS::opencl_constant; } + /// \returns Target specific vtbl ptr address space. + unsigned getVtblPtrAddressSpace() const override { +// \todo: We currently have address spaces defined in AMDGPU Backend. It +// would be nice if we could use it here instead of using bare numbers (same +// applies to getDWARFAddressSpace). +return 2; // constant. + } + + /// \returns If a target requires an address within a target specific address + /// space \p AddressSpace to be converted in order to be used, then return the + /// corresponding target specific DWARF address space. + /// + /// \returns Otherwise return None and no conversion will be emitted in the + /// DWARF. + Optional getDWARFAddressSpace( + unsigned AddressSpace) const override { +switch (AddressSpace) { +case 0: // LLVM Private. + return 1; // DWARF Private. +case 3: // LLVM Local. + return 2; // DWARF Local. +default: + return None; +} + } + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { switch (CC) { default: Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=297321&r1=297320&r2=297321&view=diff == --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Wed Mar 8 17:56:48 2017 @@ -816,17 +816,19 @@ llvm::DIType *CGDebugInfo::CreatePointer // Bit size, align and offset of the type. // Size is always the size of a pointer. We can't use getTypeSize here // because that does not return the correct value for references. - unsigned AS = CGM.getContext().getTargetAddressSpace(PointeeTy); - uint64_t Size = CGM.getTarget().getPointerWidth(AS); + unsigned AddressSpace = CGM.getContext().getTargetAddressSpace(PointeeTy); + uint64_t Size = CGM.getTarget().getPointerWidth(AddressSpace); auto Align = getTypeAlignIfRequired(Ty, CGM.getContext()); + Optional DWARFAddressSpace = + CGM.getTarget().getDWARFAddressSpace(AddressSpace); if (Tag == llvm::dwarf::DW_TAG_reference_type || Tag == llvm::dwarf::DW_TAG_rvalue_reference_type) return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit), -Size, Align); +Size, Align, DWARFAddressSpace); else return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size, - Align); + Align, DWARFAddressSpace); } llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name, @@ -1631,8 +1633,13 @@ llvm::DIType *CGDebugInfo::getOrCreateVT llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy); llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements); unsigned Size = Context.getT
r297322 - Defensively ensure that GetExternalDeclStmt protects itself from nested deserialization
Author: dblaikie Date: Wed Mar 8 17:57:08 2017 New Revision: 297322 URL: http://llvm.org/viewvc/llvm-project?rev=297322&view=rev Log: Defensively ensure that GetExternalDeclStmt protects itself from nested deserialization Modified: cfe/trunk/lib/Serialization/ASTReader.cpp Modified: cfe/trunk/lib/Serialization/ASTReader.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=297322&r1=297321&r2=297322&view=diff == --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReader.cpp Wed Mar 8 17:57:08 2017 @@ -6811,6 +6811,9 @@ Stmt *ASTReader::GetExternalDeclStmt(uin // Offset here is a global offset across the entire chain. RecordLocation Loc = getLocalBitOffset(Offset); Loc.F->DeclsCursor.JumpToBit(Loc.Offset); + assert(NumCurrentElementsDeserializing == 0 && + "should not be called while already deserializing"); + Deserializing D(this); return ReadStmtFromStream(*Loc.F); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30762: [ubsan] Add a nullability sanitizer
aprantl added inline comments. Comment at: docs/UndefinedBehaviorSanitizer.rst:98 + pointer as a function parameter which is annotated with ``_Nonnull``, + or assigning null to a lvalue marked ``_Nonnull``. You can enable + just the return value check with ``-fsanitize=nullability-return``, s/a/an/ Comment at: docs/UndefinedBehaviorSanitizer.rst:99 + or assigning null to a lvalue marked ``_Nonnull``. You can enable + just the return value check with ``-fsanitize=nullability-return``, + the assignment check with ``-fsanitize=nullability-assign``, and the Can you rephrase this without using 2nd person? Comment at: lib/CodeGen/CGCall.cpp:2926 +void CodeGenFunction::EmitReturnValueCheck(llvm::Value *RV, + SourceLocation EndLoc) { + if (!CurCodeDecl) This function could use some comments. Comment at: lib/CodeGen/CGCall.cpp:3301 +CheckKind = SanitizerKind::NonnullAttribute; + } else { +if (!PVD) comment what this early return means? Comment at: lib/CodeGen/CGDecl.cpp:676 +void CodeGenFunction::EmitNullabilityCheck(LValue Dst, llvm::Value *Src, + SourceLocation Loc) { + if (!SanOpts.has(SanitizerKind::NullabilityAssign)) Comment what the check is doing? Comment at: lib/CodeGen/CGDecl.cpp:1911 +if (auto Nullability = Ty->getNullability(getContext())) { + if (Nullability && *Nullability == NullabilityKind::NonNull) { +SanitizerScope SanScope(this); Is this a typo, or do you. really want `Nullability` here? Asking because everywhere else there is a check for `! Nullability && *Nullability == NullabilityKind::NonNull`. Ans should this condition be factored out? Comment at: lib/CodeGen/CodeGenFunction.h:1766 + /// \brief Emit a test that checks if the return value \p RV is nonnull. + void EmitReturnValueCheck(llvm::Value *RV, SourceLocation EndLoc); The \brief is redundant. We run doxygen with autobrief. Comment at: lib/CodeGen/CodeGenFunction.h:3474 + /// \brief Emit a test that checks if \p Src is nonnull if \p Dst is + /// annotated as nonnull. ditto https://reviews.llvm.org/D30762 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297324 - [analyzer] Add bug visitor for taint checker.
Author: zaks Date: Wed Mar 8 18:01:07 2017 New Revision: 297324 URL: http://llvm.org/viewvc/llvm-project?rev=297324&view=rev Log: [analyzer] Add bug visitor for taint checker. Add a bug visitor to the taint checker to make it easy to distinguish where the tainted value originated. This is especially useful when the original taint source is obscured by complex data flow. A patch by Vlad Tsyrklevich! Differential Revision: https://reviews.llvm.org/D30289 Added: cfe/trunk/test/Analysis/taint-diagnostic-visitor.c Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp?rev=297324&r1=297323&r2=297324&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp Wed Mar 8 18:01:07 2017 @@ -101,6 +101,22 @@ private: bool generateReportIfTainted(const Expr *E, const char Msg[], CheckerContext &C) const; + /// The bug visitor prints a diagnostic message at the location where a given + /// variable was tainted. + class TaintBugVisitor + : public BugReporterVisitorImpl { + private: +const SVal V; + + public: +TaintBugVisitor(const SVal V) : V(V) {} +void Profile(llvm::FoldingSetNodeID &ID) const override { ID.Add(V); } + +std::shared_ptr VisitNode(const ExplodedNode *N, + const ExplodedNode *PrevN, + BugReporterContext &BRC, + BugReport &BR) override; + }; typedef SmallVector ArgVector; @@ -194,6 +210,28 @@ const char GenericTaintChecker::MsgTaint /// points to data, which should be tainted on return. REGISTER_SET_WITH_PROGRAMSTATE(TaintArgsOnPostVisit, unsigned) +std::shared_ptr +GenericTaintChecker::TaintBugVisitor::VisitNode(const ExplodedNode *N, +const ExplodedNode *PrevN, BugReporterContext &BRC, BugReport &BR) { + + // Find the ExplodedNode where the taint was first introduced + if (!N->getState()->isTainted(V) || PrevN->getState()->isTainted(V)) +return nullptr; + + const Stmt *S = PathDiagnosticLocation::getStmt(N); + if (!S) +return nullptr; + + const LocationContext *NCtx = N->getLocationContext(); + PathDiagnosticLocation L = + PathDiagnosticLocation::createBegin(S, BRC.getSourceManager(), NCtx); + if (!L.isValid() || !L.asLocation().isValid()) +return nullptr; + + return std::make_shared( + L, "Taint originated here"); +} + GenericTaintChecker::TaintPropagationRule GenericTaintChecker::TaintPropagationRule::getTaintPropagationRule( const FunctionDecl *FDecl, @@ -635,8 +673,13 @@ bool GenericTaintChecker::generateReport // Check for taint. ProgramStateRef State = C.getState(); - if (!State->isTainted(getPointedToSymbol(C, E)) && - !State->isTainted(E, C.getLocationContext())) + const SymbolRef PointedToSym = getPointedToSymbol(C, E); + SVal TaintedSVal; + if (State->isTainted(PointedToSym)) +TaintedSVal = nonloc::SymbolVal(PointedToSym); + else if (State->isTainted(E, C.getLocationContext())) +TaintedSVal = C.getSVal(E); + else return false; // Generate diagnostic. @@ -644,6 +687,7 @@ bool GenericTaintChecker::generateReport initBugType(); auto report = llvm::make_unique(*BT, Msg, N); report->addRange(E->getSourceRange()); +report->addVisitor(llvm::make_unique(TaintedSVal)); C.emitReport(std::move(report)); return true; } Added: cfe/trunk/test/Analysis/taint-diagnostic-visitor.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/taint-diagnostic-visitor.c?rev=297324&view=auto == --- cfe/trunk/test/Analysis/taint-diagnostic-visitor.c (added) +++ cfe/trunk/test/Analysis/taint-diagnostic-visitor.c Wed Mar 8 18:01:07 2017 @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.security.taint,core -analyzer-output=text -verify %s + +// This file is for testing enhanced diagnostics produced by the GenericTaintChecker + +int scanf(const char *restrict format, ...); +int system(const char *command); + +void taintDiagnostic() +{ + char buf[128]; + scanf("%s", buf); // expected-note {{Taint originated here}} + system(buf); // expected-warning {{Untrusted data is passed to a system call}} // expected-note {{Untrusted data is passed to a system call (CERT/STR02-C. Sanitize data passed to complex subsystems)}} +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo
r297325 - [analyzer] Improve usability of ExprInspectionChecker
Author: zaks Date: Wed Mar 8 18:01:10 2017 New Revision: 297325 URL: http://llvm.org/viewvc/llvm-project?rev=297325&view=rev Log: [analyzer] Improve usability of ExprInspectionChecker Some of the magic functions take arguments of arbitrary type. However, for semantic correctness, the compiler still requires a declaration of these functions with the correct type. Since C does not have argument-type-overloaded function, this made those functions hard to use in C code. Improve this situation by allowing arbitrary suffixes in the affected magic functions' names, thus allowing the user to create different declarations for different types. A patch by Keno Fischer! Differential Revision: https://reviews.llvm.org/D30589 Added: cfe/trunk/test/Analysis/explain-svals.c Modified: cfe/trunk/docs/analyzer/DebugChecks.rst cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp Modified: cfe/trunk/docs/analyzer/DebugChecks.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/analyzer/DebugChecks.rst?rev=297325&r1=297324&r2=297325&view=diff == --- cfe/trunk/docs/analyzer/DebugChecks.rst (original) +++ cfe/trunk/docs/analyzer/DebugChecks.rst Wed Mar 8 18:01:10 2017 @@ -178,15 +178,21 @@ ExprInspection checks This function explains the value of its argument in a human-readable manner in the warning message. You can make as many overrides of its prototype in the test code as necessary to explain various integral, pointer, - or even record-type values. + or even record-type values. To simplify usage in C code (where overloading + the function declaration is not allowed), you may append an arbitrary suffix + to the function name, without affecting functionality. Example usage:: void clang_analyzer_explain(int); void clang_analyzer_explain(void *); +// Useful in C code +void clang_analyzer_explain_int(int); + void foo(int param, void *ptr) { clang_analyzer_explain(param); // expected-warning{{argument 'param'}} + clang_analyzer_explain_int(param); // expected-warning{{argument 'param'}} if (!ptr) clang_analyzer_explain(ptr); // expected-warning{{memory address '0'}} } Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp?rev=297325&r1=297324&r2=297325&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp Wed Mar 8 18:01:10 2017 @@ -72,8 +72,8 @@ bool ExprInspectionChecker::evalCall(con &ExprInspectionChecker::analyzerWarnIfReached) .Case("clang_analyzer_warnOnDeadSymbol", &ExprInspectionChecker::analyzerWarnOnDeadSymbol) -.Case("clang_analyzer_explain", &ExprInspectionChecker::analyzerExplain) -.Case("clang_analyzer_dump", &ExprInspectionChecker::analyzerDump) +.StartsWith("clang_analyzer_explain", &ExprInspectionChecker::analyzerExplain) +.StartsWith("clang_analyzer_dump", &ExprInspectionChecker::analyzerDump) .Case("clang_analyzer_getExtent", &ExprInspectionChecker::analyzerGetExtent) .Case("clang_analyzer_printState", &ExprInspectionChecker::analyzerPrintState) Added: cfe/trunk/test/Analysis/explain-svals.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/explain-svals.c?rev=297325&view=auto == --- cfe/trunk/test/Analysis/explain-svals.c (added) +++ cfe/trunk/test/Analysis/explain-svals.c Wed Mar 8 18:01:10 2017 @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core.builtin,debug.ExprInspection,unix.cstring -verify %s + +struct S { + int z; +}; + +void clang_analyzer_explain_int(int); +void clang_analyzer_explain_voidp(void *); +void clang_analyzer_explain_S(struct S); + +int glob; + +void test_1(int param, void *ptr) { + clang_analyzer_explain_voidp(&glob); // expected-warning-re^pointer to global variable 'glob'$ + clang_analyzer_explain_int(param); // expected-warning-re^argument 'param'$ + clang_analyzer_explain_voidp(ptr); // expected-warning-re^argument 'ptr'$ + if (param == 42) +clang_analyzer_explain_int(param); // expected-warning-re^signed 32-bit integer '42'$ +} + +void test_2(struct S s) { + clang_analyzer_explain_S(s); //expected-warning-re^lazily frozen compound value of parameter 's'$ + clang_analyzer_explain_voidp(&s); // expected-warning-re^pointer to parameter 's'$ + clang_analyzer_explain_int(s.z); // expected-warning-re^initial value of field 'z' of parameter 's'$ +} ___ cfe-commits ma