[PATCH] D31650: [Analyzer] Detect when function pointer is freed
AndersRonnholm created this revision. The MallocChecker does not currently detect freeing of function pointers. Example code. void (*fnptr)(int); void freeIndirectFunctionPtr() { void *p = (void*)fnptr; free(p); // expected-warning {{Argument to free() points to a function pointer}} } Repository: rL LLVM https://reviews.llvm.org/D31650 Files: lib/StaticAnalyzer/Checkers/MallocChecker.cpp test/Analysis/malloc.c Index: test/Analysis/malloc.c === --- test/Analysis/malloc.c +++ test/Analysis/malloc.c @@ -1774,6 +1774,16 @@ return ok; // no warning } +void (*fnptr)(int); +void freeIndirectFunctionPtr() { + void *p = (void*)fnptr; + free(p); // expected-warning {{Argument to free() points to a function pointer}} +} + +void freeFunctionPtr() { + free((void*)fnptr); // expected-warning {{Argument to free() is a function pointer}} +} + // // False negatives. Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp === --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -392,6 +392,10 @@ void ReportUseZeroAllocated(CheckerContext &C, SourceRange Range, SymbolRef Sym) const; + void ReportFunctionPointerFree(CheckerContext &C, SVal ArgVal, + SourceRange Range, const Expr *DeallocExpr, + const Expr *ArgExpr) const; + /// Find the location of the allocation for Sym on the path leading to the /// exploded node N. LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym, @@ -1516,6 +1520,12 @@ } } + if (SymBase->getType()->isFunctionPointerType()) { +ReportFunctionPointerFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr, + ArgExpr); +return nullptr; + } + ReleasedAllocated = (RsBase != nullptr) && (RsBase->isAllocated() || RsBase->isAllocatedOfSizeZero()); @@ -1976,6 +1986,47 @@ } } +void MallocChecker::ReportFunctionPointerFree(CheckerContext &C, SVal ArgVal, + SourceRange Range, + const Expr *DeallocExpr, + const Expr *ArgExpr) const { + + if (!ChecksEnabled[CK_MallocChecker]) +return; + + Optional CheckKind = + getCheckIfTracked(C, DeallocExpr); + if (!CheckKind.hasValue()) +return; + + if (ExplodedNode *N = C.generateErrorNode()) { +if (!BT_BadFree[*CheckKind]) + BT_BadFree[*CheckKind].reset( + new BugType(CheckNames[*CheckKind], "Bad free", "Memory Error")); + +SmallString<100> Buf; +llvm::raw_svector_ostream Os(Buf); + +const MemRegion *MR = ArgVal.getAsRegion(); +while (const ElementRegion *ER = dyn_cast_or_null(MR)) + MR = ER->getSuperRegion(); + +Os << "Argument to "; +if (!printAllocDeallocName(Os, C, DeallocExpr)) + Os << "deallocator"; + +if (ArgExpr->IgnoreParenCasts()->getType()->isFunctionPointerType()) + Os << " is a function pointer"; +else + Os << " points to a function pointer"; + +auto R = llvm::make_unique(*BT_BadFree[*CheckKind], Os.str(), N); +R->markInteresting(MR); +R->addRange(Range); +C.emitReport(std::move(R)); + } +} + ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE, bool FreesOnFail, Index: test/Analysis/malloc.c === --- test/Analysis/malloc.c +++ test/Analysis/malloc.c @@ -1774,6 +1774,16 @@ return ok; // no warning } +void (*fnptr)(int); +void freeIndirectFunctionPtr() { + void *p = (void*)fnptr; + free(p); // expected-warning {{Argument to free() points to a function pointer}} +} + +void freeFunctionPtr() { + free((void*)fnptr); // expected-warning {{Argument to free() is a function pointer}} +} + // // False negatives. Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp === --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -392,6 +392,10 @@ void ReportUseZeroAllocated(CheckerContext &C, SourceRange Range, SymbolRef Sym) const; + void ReportFunctionPointerFree(CheckerContext &C, SVal ArgVal, + SourceRange Range, const Expr *DeallocExpr, + const Expr *ArgExpr) const; + /// Find the location of the allocation for Sym on the path leading to the /// e
[PATCH] D31650: [Analyzer] Detect when function pointer is freed
NoQ added a comment. Hello, thanks for the patch! Because we already warn on freeing concrete function pointers, eg. void foo() { free(&foo); } this is a useful addition. Is freeing function pointers always undefined? I wonder what happens if we take some JIT-enabled javascript engine, maybe with some on-stack replacement of theirs, it may `malloc()` a memory and use it as a function, and then eventually it'd need to free it by design. However, because we're analyzing a small part of the program, we may fail to see in the analyzer that the symbolic pointer originally comes from `malloc()`. Would such rare but important users be able to avoid/suppress the warning? Comment at: test/Analysis/malloc.c:1780 + void *p = (void*)fnptr; + free(p); // expected-warning {{Argument to free() points to a function pointer}} +} Nope, it doesn't point to a function pointer. It's still the same function pointer. Also, freeing a pointer to a function pointer is not a bug. Repository: rL LLVM https://reviews.llvm.org/D31650 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D29768: [TargetInfo] Set 'UseSignedCharForObjCBool' to false by default
arphaman added a comment. Ping. Repository: rL LLVM https://reviews.llvm.org/D29768 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r299419 - [clang-rename] Support renaming qualified symbol
Author: hokein Date: Tue Apr 4 04:30:06 2017 New Revision: 299419 URL: http://llvm.org/viewvc/llvm-project?rev=299419&view=rev Log: [clang-rename] Support renaming qualified symbol Summary: The patch adds a new feature for renaming qualified symbol references. Unlike orginal clang-rename behavior, when renaming a qualified symbol to a new qualified symbol (e.g "A::Foo" => "B::Bar"), this new rename behavior will consider the prefix qualifiers of the symbol, and calculate the new prefix qualifiers. It aims to add as few additional qualifiers as possible. As this is an early version (only supports renaming classes), I don't change current clang-rename interfaces at the moment, and would like to keep its (command-line tool) behavior. So I added new interfaces for the prototype. In the long run, these interfaces should be unified. No functionality changes in original clang-rename command-line tool. This patch also contains a few bug fixes of clang-rename which are discovered by the new unittest: * fix a potential nullptr accessment when class declaration doesn't have definition. * add USRs of nested declartaions in "getNamedDeclFor". Reviewers: ioeric Reviewed By: ioeric Subscribers: alexfh, cfe-commits, mgorny Differential Revision: https://reviews.llvm.org/D31176 Added: clang-tools-extra/trunk/unittests/clang-rename/ClangRenameTest.h - copied, changed from r299340, clang-tools-extra/trunk/unittests/clang-rename/ClangRenameTests.cpp clang-tools-extra/trunk/unittests/clang-rename/RenameClassTest.cpp Removed: clang-tools-extra/trunk/unittests/clang-rename/ClangRenameTests.cpp Modified: clang-tools-extra/trunk/clang-rename/CMakeLists.txt clang-tools-extra/trunk/clang-rename/RenamingAction.cpp clang-tools-extra/trunk/clang-rename/RenamingAction.h clang-tools-extra/trunk/clang-rename/USRFinder.cpp clang-tools-extra/trunk/clang-rename/USRFindingAction.cpp clang-tools-extra/trunk/clang-rename/USRLocFinder.cpp clang-tools-extra/trunk/clang-rename/USRLocFinder.h clang-tools-extra/trunk/unittests/clang-rename/CMakeLists.txt Modified: clang-tools-extra/trunk/clang-rename/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-rename/CMakeLists.txt?rev=299419&r1=299418&r2=299419&view=diff == --- clang-tools-extra/trunk/clang-rename/CMakeLists.txt (original) +++ clang-tools-extra/trunk/clang-rename/CMakeLists.txt Tue Apr 4 04:30:06 2017 @@ -13,6 +13,7 @@ add_clang_library(clangRename clangIndex clangLex clangToolingCore + clangToolingRefactor ) add_subdirectory(tool) Modified: clang-tools-extra/trunk/clang-rename/RenamingAction.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-rename/RenamingAction.cpp?rev=299419&r1=299418&r2=299419&view=diff == --- clang-tools-extra/trunk/clang-rename/RenamingAction.cpp (original) +++ clang-tools-extra/trunk/clang-rename/RenamingAction.cpp Tue Apr 4 04:30:06 2017 @@ -84,10 +84,52 @@ private: bool PrintLocations; }; +// A renamer to rename symbols which are identified by a give USRList to +// new name. +// +// FIXME: Merge with the above RenamingASTConsumer. +class USRSymbolRenamer: public ASTConsumer { +public: + USRSymbolRenamer(const std::vector &NewNames, + const std::vector> &USRList, + std::map &FileToReplaces) + : NewNames(NewNames), USRList(USRList), FileToReplaces(FileToReplaces) { +assert(USRList.size() == NewNames.size()); + } + + void HandleTranslationUnit(ASTContext &Context) override { +for (unsigned I = 0; I < NewNames.size(); ++I) { + // FIXME: Apply AtomicChanges directly once the refactoring APIs are + // ready. + auto AtomicChanges = createRenameAtomicChanges( + USRList[I], NewNames[I], Context.getTranslationUnitDecl()); + for (const auto AtomicChange : AtomicChanges) { +for (const auto &Replace : AtomicChange.getReplacements()) { + llvm::Error Err = FileToReplaces[Replace.getFilePath()].add(Replace); + if (Err) { +llvm::errs() << "Renaming failed in " << Replace.getFilePath() + << "! " << llvm::toString(std::move(Err)) << "\n"; + } + } + } +} + } + +private: + const std::vector &NewNames; + const std::vector> &USRList; + std::map &FileToReplaces; +}; + std::unique_ptr RenamingAction::newASTConsumer() { return llvm::make_unique(NewNames, PrevNames, USRList, FileToReplaces, PrintLocations); } +std::unique_ptr QualifiedRenamingAction::newASTConsumer() { + return llvm::make_unique( + NewNames, USRList, FileToReplaces); +} + } // namespace rename } // namespace clang Modified: clang-tools-extra/trunk/clang-rename/RenamingAction.h URL: http://llv
[PATCH] D31176: [clang-rename] Support renaming qualified symbol
This revision was automatically updated to reflect the committed changes. Closed by commit rL299419: [clang-rename] Support renaming qualified symbol (authored by hokein). Changed prior to commit: https://reviews.llvm.org/D31176?vs=93474&id=94021#toc Repository: rL LLVM https://reviews.llvm.org/D31176 Files: clang-tools-extra/trunk/clang-rename/CMakeLists.txt clang-tools-extra/trunk/clang-rename/RenamingAction.cpp clang-tools-extra/trunk/clang-rename/RenamingAction.h clang-tools-extra/trunk/clang-rename/USRFinder.cpp clang-tools-extra/trunk/clang-rename/USRFindingAction.cpp clang-tools-extra/trunk/clang-rename/USRLocFinder.cpp clang-tools-extra/trunk/clang-rename/USRLocFinder.h clang-tools-extra/trunk/unittests/clang-rename/CMakeLists.txt clang-tools-extra/trunk/unittests/clang-rename/ClangRenameTest.h clang-tools-extra/trunk/unittests/clang-rename/ClangRenameTests.cpp clang-tools-extra/trunk/unittests/clang-rename/RenameClassTest.cpp Index: clang-tools-extra/trunk/unittests/clang-rename/ClangRenameTest.h === --- clang-tools-extra/trunk/unittests/clang-rename/ClangRenameTest.h +++ clang-tools-extra/trunk/unittests/clang-rename/ClangRenameTest.h @@ -0,0 +1,112 @@ +//===-- ClangRenameTests.cpp - clang-rename unit tests ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "RenamingAction.h" +#include "USRFindingAction.h" +#include "unittests/Tooling/RewriterTestContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemOptions.h" +#include "clang/Basic/VirtualFileSystem.h" +#include "clang/Format/Format.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/PCHContainerOperations.h" +#include "clang/Tooling/Refactoring.h" +#include "clang/Tooling/Tooling.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/MemoryBuffer.h" +#include "gtest/gtest.h" +#include +#include +#include + +namespace clang { +namespace clang_rename { +namespace test { + +struct Case { + std::string Before; + std::string After; + std::string OldName; + std::string NewName; +}; + +class ClangRenameTest : public testing::Test, +public testing::WithParamInterface { +protected: + void AppendToHeader(StringRef Code) { HeaderContent += Code.str(); } + + std::string runClangRenameOnCode(llvm::StringRef Code, + llvm::StringRef OldName, + llvm::StringRef NewName) { +std::string NewCode; +llvm::raw_string_ostream(NewCode) << llvm::format( +"#include \"%s\"\n%s", HeaderName.c_str(), Code.str().c_str()); +tooling::FileContentMappings FileContents = {{HeaderName, HeaderContent}, + {CCName, NewCode}}; +clang::RewriterTestContext Context; +Context.createInMemoryFile(HeaderName, HeaderContent); +clang::FileID InputFileID = Context.createInMemoryFile(CCName, NewCode); + +rename::USRFindingAction FindingAction({}, {OldName}); +std::unique_ptr USRFindingActionFactory = +tooling::newFrontendActionFactory(&FindingAction); + +if (!tooling::runToolOnCodeWithArgs( +USRFindingActionFactory->create(), NewCode, {"-std=c++11"}, CCName, +"clang-rename", std::make_shared(), +FileContents)) + return ""; + +const std::vector> &USRList = +FindingAction.getUSRList(); +std::vector NewNames = {NewName}; +std::map FileToReplacements; +rename::QualifiedRenamingAction RenameAction(NewNames, USRList, + FileToReplacements); +auto RenameActionFactory = tooling::newFrontendActionFactory(&RenameAction); +if (!tooling::runToolOnCodeWithArgs( +RenameActionFactory->create(), NewCode, {"-std=c++11"}, CCName, +"clang-rename", std::make_shared(), +FileContents)) + return ""; + +formatAndApplyAllReplacements(FileToReplacements, Context.Rewrite, "llvm"); +return Context.getRewrittenText(InputFileID); + } + + void CompareSnippets(StringRef Expected, StringRef Actual) { +std::string ExpectedCode; +llvm::raw_string_ostream(ExpectedCode) << llvm::format( +"#include \"%s\"\n%s", HeaderName.c_str(), Expected.str().c_str()); +EXPECT_EQ(format(ExpectedCode), format(Actual)); + } + + std::string format(llvm::StringRef Code) { +tooling::Replacements Replaces = format::reformat( +format::getLLVMStyle(), Code, {tooling::Range(0, Code.size())}); +auto ChangedCode = tooling::applyAllRepla
[PATCH] D31652: [clang-format] Recognize Java logical shift assignment operator
bradfier created this revision. Herald added a subscriber: klimek. At present, clang-format mangles Java containing logical shift assignment operators ('>>>=' or '<<<='), splitting them in two, resulting in invalid code: public class Minimal { public void func(String args) { int i = 42; -i >>>= 1; +i >> >= 1; return i; } } This adds the combined assignment forms for logical shifts to the lexer, so clang-format sees them as single tokens and doesn't try to insert whitespace.. Repository: rL LLVM https://reviews.llvm.org/D31652 Files: include/clang/Basic/LangOptions.def include/clang/Basic/TokenKinds.def lib/Format/Format.cpp lib/Lex/Lexer.cpp unittests/Format/FormatTestJava.cpp Index: unittests/Format/FormatTestJava.cpp === --- unittests/Format/FormatTestJava.cpp +++ unittests/Format/FormatTestJava.cpp @@ -522,5 +522,17 @@ " void f() {}")); } +TEST_F(FormatTestJava, RetainsLogicalShiftAssignments) { +verifyFormat("void f() {\n" + " int a = 1;\n" + " a >>>= 1;\n" + "}"); +verifyFormat("void f() {\n" + " int a = 1;\n" + " a <<<= 1;\n" + "}"); +} + + } // end namespace tooling } // end namespace clang Index: lib/Lex/Lexer.cpp === --- lib/Lex/Lexer.cpp +++ lib/Lex/Lexer.cpp @@ -2967,7 +2967,7 @@ Result.setFlag(Token::LeadingSpace); } - unsigned SizeTmp, SizeTmp2; // Temporaries for use in cases below. + unsigned SizeTmp, SizeTmp2, SizeTmp3; // Temporaries for use in cases below. // Read a character, advancing over it. char Char = getAndAdvanceChar(CurPtr, Result); @@ -3449,6 +3449,14 @@ Kind = tok::lesslessless; CurPtr = ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result), SizeTmp2, Result); + } else if (LangOpts.Java && After == '<') { + char Fourth = getCharAndSize(CurPtr+SizeTmp+SizeTmp2, SizeTmp3); + if (Fourth == '=') { + Kind = tok::lesslesslessequal; + CurPtr = ConsumeChar(ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result), + SizeTmp2, Result), + SizeTmp3, Result); + } } else { CurPtr = ConsumeChar(CurPtr, SizeTmp, Result); Kind = tok::lessless; @@ -3505,6 +3513,14 @@ Kind = tok::greatergreatergreater; CurPtr = ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result), SizeTmp2, Result); + } else if (LangOpts.Java && After == '>') { + char Fourth = getCharAndSize(CurPtr+SizeTmp+SizeTmp2, SizeTmp3); + if (Fourth == '=') { + Kind = tok::greatergreatergreaterequal; + CurPtr = ConsumeChar(ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result), + SizeTmp2, Result), + SizeTmp3, Result); + } } else { CurPtr = ConsumeChar(CurPtr, SizeTmp, Result); Kind = tok::greatergreater; Index: lib/Format/Format.cpp === --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -1902,6 +1902,7 @@ LangOpts.ObjC2 = 1; LangOpts.MicrosoftExt = 1;// To get kw___try, kw___finally. LangOpts.DeclSpecKeyword = 1; // To get __declspec. + LangOpts.Java = Style.Language == FormatStyle::LK_Java; return LangOpts; } Index: include/clang/Basic/TokenKinds.def === --- include/clang/Basic/TokenKinds.def +++ include/clang/Basic/TokenKinds.def @@ -225,6 +225,10 @@ // CL support PUNCTUATOR(caretcaret,"^^") +// Java support (for clang-format only) +PUNCTUATOR(greatergreatergreaterequal, ">>>=") +PUNCTUATOR(lesslesslessequal, "<<<=") + // C99 6.4.1: Keywords. These turn into kw_* tokens. // Flags allowed: // KEYALL - This is a keyword in all variants of C and C++, or it Index: include/clang/Basic/LangOptions.def === --- include/clang/Basic/LangOptions.def +++ include/clang/Basic/LangOptions.def @@ -92,6 +92,7 @@ LANGOPT(CPlusPlus1z , 1, 0, "C++1z") LANGOPT(ObjC1 , 1, 0, "Objective-C 1") LANGOPT(ObjC2 , 1, 0, "Objective-C 2") +LANGOPT(Java , 1, 0, "Java") BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0, "Objective-C auto-synthesized properties") BENIGN_LANGOPT(EncodeExtendedBlockSig , 1, 0, ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r299421 - [clangd] Add code completion support
Author: krasimir Date: Tue Apr 4 04:46:39 2017 New Revision: 299421 URL: http://llvm.org/viewvc/llvm-project?rev=299421&view=rev Log: [clangd] Add code completion support Summary: Adds code completion support to clangd. Reviewers: bkramer, malaperle-ericsson Reviewed By: bkramer, malaperle-ericsson Subscribers: stanionascu, malaperle-ericsson, cfe-commits Differential Revision: https://reviews.llvm.org/D31328 Added: clang-tools-extra/trunk/test/clangd/completion.test Modified: clang-tools-extra/trunk/clangd/ASTManager.cpp clang-tools-extra/trunk/clangd/ASTManager.h clang-tools-extra/trunk/clangd/ClangDMain.cpp clang-tools-extra/trunk/clangd/Protocol.cpp clang-tools-extra/trunk/clangd/Protocol.h clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp clang-tools-extra/trunk/clangd/ProtocolHandlers.h clang-tools-extra/trunk/test/clangd/formatting.test Modified: clang-tools-extra/trunk/clangd/ASTManager.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ASTManager.cpp?rev=299421&r1=299420&r2=299421&view=diff == --- clang-tools-extra/trunk/clangd/ASTManager.cpp (original) +++ clang-tools-extra/trunk/clangd/ASTManager.cpp Tue Apr 4 04:46:39 2017 @@ -83,50 +83,54 @@ void ASTManager::runWorker() { } void ASTManager::parseFileAndPublishDiagnostics(StringRef File) { - auto &Unit = ASTs[File]; // Only one thread can access this at a time. + DiagnosticToReplacementMap LocalFixIts; // Temporary storage + std::string Diagnostics; + { +std::lock_guard ASTGuard(ASTLock); +auto &Unit = ASTs[File]; // Only one thread can access this at a time. - if (!Unit) { -Unit = createASTUnitForFile(File, this->Store); - } else { -// Do a reparse if this wasn't the first parse. -// FIXME: This might have the wrong working directory if it changed in the -// meantime. -Unit->Reparse(PCHs, getRemappedFiles(this->Store)); - } +if (!Unit) { + Unit = createASTUnitForFile(File, this->Store); +} else { + // Do a reparse if this wasn't the first parse. + // FIXME: This might have the wrong working directory if it changed in the + // meantime. + Unit->Reparse(PCHs, getRemappedFiles(this->Store)); +} - if (!Unit) -return; +if (!Unit) + return; - // Send the diagnotics to the editor. - // FIXME: If the diagnostic comes from a different file, do we want to - // show them all? Right now we drop everything not coming from the - // main file. - std::string Diagnostics; - DiagnosticToReplacementMap LocalFixIts; // Temporary storage - for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(), - DEnd = Unit->stored_diag_end(); - D != DEnd; ++D) { -if (!D->getLocation().isValid() || -!D->getLocation().getManager().isInMainFile(D->getLocation())) - continue; -Position P; -P.line = D->getLocation().getSpellingLineNumber() - 1; -P.character = D->getLocation().getSpellingColumnNumber(); -Range R = {P, P}; -Diagnostics += -R"({"range":)" + Range::unparse(R) + -R"(,"severity":)" + std::to_string(getSeverity(D->getLevel())) + -R"(,"message":")" + llvm::yaml::escape(D->getMessage()) + -R"("},)"; - -// We convert to Replacements to become independent of the SourceManager. -clangd::Diagnostic Diag = {R, getSeverity(D->getLevel()), D->getMessage()}; -auto &FixItsForDiagnostic = LocalFixIts[Diag]; -for (const FixItHint &Fix : D->getFixIts()) { - FixItsForDiagnostic.push_back(clang::tooling::Replacement( - Unit->getSourceManager(), Fix.RemoveRange, Fix.CodeToInsert)); +// Send the diagnotics to the editor. +// FIXME: If the diagnostic comes from a different file, do we want to +// show them all? Right now we drop everything not coming from the +// main file. +for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(), + DEnd = Unit->stored_diag_end(); + D != DEnd; ++D) { + if (!D->getLocation().isValid() || + !D->getLocation().getManager().isInMainFile(D->getLocation())) +continue; + Position P; + P.line = D->getLocation().getSpellingLineNumber() - 1; + P.character = D->getLocation().getSpellingColumnNumber(); + Range R = {P, P}; + Diagnostics += + R"({"range":)" + Range::unparse(R) + + R"(,"severity":)" + std::to_string(getSeverity(D->getLevel())) + + R"(,"message":")" + llvm::yaml::escape(D->getMessage()) + + R"("},)"; + + // We convert to Replacements to become independent of the SourceManager. + clangd::Diagnostic Diag = {R, getSeverity(D->getLevel()), + D->getMessage()}; + auto &FixItsForDiagnostic = LocalFixIts[Diag]; + for (const FixItHint &Fix : D->getFixIts()) { +
[PATCH] D31328: [clangd] Add code completion support
This revision was automatically updated to reflect the committed changes. Closed by commit rL299421: [clangd] Add code completion support (authored by krasimir). Changed prior to commit: https://reviews.llvm.org/D31328?vs=92948&id=94026#toc Repository: rL LLVM https://reviews.llvm.org/D31328 Files: clang-tools-extra/trunk/clangd/ASTManager.cpp clang-tools-extra/trunk/clangd/ASTManager.h clang-tools-extra/trunk/clangd/ClangDMain.cpp clang-tools-extra/trunk/clangd/Protocol.cpp clang-tools-extra/trunk/clangd/Protocol.h clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp clang-tools-extra/trunk/clangd/ProtocolHandlers.h clang-tools-extra/trunk/test/clangd/completion.test clang-tools-extra/trunk/test/clangd/formatting.test Index: clang-tools-extra/trunk/clangd/Protocol.cpp === --- clang-tools-extra/trunk/clangd/Protocol.cpp +++ clang-tools-extra/trunk/clangd/Protocol.cpp @@ -570,3 +570,75 @@ } return Result; } + +llvm::Optional +TextDocumentPositionParams::parse(llvm::yaml::MappingNode *Params) { + TextDocumentPositionParams Result; + for (auto &NextKeyValue : *Params) { +auto *KeyString = dyn_cast(NextKeyValue.getKey()); +if (!KeyString) + return llvm::None; + +llvm::SmallString<10> KeyStorage; +StringRef KeyValue = KeyString->getValue(KeyStorage); +auto *Value = +dyn_cast_or_null(NextKeyValue.getValue()); +if (!Value) + return llvm::None; + +llvm::SmallString<10> Storage; +if (KeyValue == "textDocument") { + auto Parsed = TextDocumentIdentifier::parse(Value); + if (!Parsed) +return llvm::None; + Result.textDocument = std::move(*Parsed); +} else if (KeyValue == "position") { + auto Parsed = Position::parse(Value); + if (!Parsed) +return llvm::None; + Result.position = std::move(*Parsed); +} else { + return llvm::None; +} + } + return Result; +} + +std::string CompletionItem::unparse(const CompletionItem &CI) { + std::string Result = "{"; + llvm::raw_string_ostream Os(Result); + assert(!CI.label.empty() && "completion item label is required"); + Os << R"("label":")" << llvm::yaml::escape(CI.label) << R"(",)"; + if (CI.kind != CompletionItemKind::Missing) +Os << R"("kind":)" << static_cast(CI.kind) << R"(",)"; + if (!CI.detail.empty()) +Os << R"("detail":")" << llvm::yaml::escape(CI.detail) << R"(",)"; + if (!CI.documentation.empty()) +Os << R"("documentation":")" << llvm::yaml::escape(CI.documentation) + << R"(",)"; + if (!CI.sortText.empty()) +Os << R"("sortText":")" << llvm::yaml::escape(CI.sortText) << R"(",)"; + if (!CI.filterText.empty()) +Os << R"("filterText":")" << llvm::yaml::escape(CI.filterText) << R"(",)"; + if (!CI.insertText.empty()) +Os << R"("insertText":")" << llvm::yaml::escape(CI.insertText) << R"(",)"; + if (CI.insertTextFormat != InsertTextFormat::Missing) { +Os << R"("insertTextFormat":")" << static_cast(CI.insertTextFormat) + << R"(",)"; + } + if (CI.textEdit) +Os << R"("textEdit":)" << TextEdit::unparse(*CI.textEdit) << ','; + if (!CI.additionalTextEdits.empty()) { +Os << R"("additionalTextEdits":[)"; +for (const auto &Edit : CI.additionalTextEdits) + Os << TextEdit::unparse(Edit) << ","; +Os.flush(); +// The list additionalTextEdits is guaranteed nonempty at this point. +// Replace the trailing comma with right brace. +Result.back() = ']'; + } + Os.flush(); + // Label is required, so Result is guaranteed to have a trailing comma. + Result.back() = '}'; + return Result; +} Index: clang-tools-extra/trunk/clangd/ClangDMain.cpp === --- clang-tools-extra/trunk/clangd/ClangDMain.cpp +++ clang-tools-extra/trunk/clangd/ClangDMain.cpp @@ -61,6 +61,8 @@ llvm::make_unique(Out, Store)); Dispatcher.registerHandler("textDocument/codeAction", llvm::make_unique(Out, AST)); + Dispatcher.registerHandler("textDocument/completion", + llvm::make_unique(Out, AST)); while (std::cin.good()) { // A Language Server Protocol message starts with a HTTP header, delimited Index: clang-tools-extra/trunk/clangd/ProtocolHandlers.h === --- clang-tools-extra/trunk/clangd/ProtocolHandlers.h +++ clang-tools-extra/trunk/clangd/ProtocolHandlers.h @@ -36,7 +36,8 @@ "documentFormattingProvider": true, "documentRangeFormattingProvider": true, "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]}, - "codeActionProvider": true + "codeActionProvider": true, + "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">"]} }}})"); } }; @@ -114,6 +115,16 @@ ASTManager &AST; }; +struct CompletionH
[PATCH] D31441: [clang-format] fix crash in NamespaceEndCommentsFixer (PR32438)
krasimir accepted this revision. krasimir added a comment. This revision is now accepted and ready to land. Great! https://reviews.llvm.org/D31441 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r299422 - Fix windows buildbot error.
Author: hokein Date: Tue Apr 4 04:53:55 2017 New Revision: 299422 URL: http://llvm.org/viewvc/llvm-project?rev=299422&view=rev Log: Fix windows buildbot error. Modified: clang-tools-extra/trunk/clang-rename/USRLocFinder.cpp Modified: clang-tools-extra/trunk/clang-rename/USRLocFinder.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-rename/USRLocFinder.cpp?rev=299422&r1=299421&r2=299422&view=diff == --- clang-tools-extra/trunk/clang-rename/USRLocFinder.cpp (original) +++ clang-tools-extra/trunk/clang-rename/USRLocFinder.cpp Tue Apr 4 04:53:55 2017 @@ -406,7 +406,7 @@ private: // Get the closest ancester which is a declaration of a given AST node. template - const Decl *getClosestAncestorDecl(ASTNodeType Node) { + const Decl *getClosestAncestorDecl(const ASTNodeType &Node) { auto Parents = Context.getParents(Node); // FIXME: figure out how to handle it when there are multiple parents. if (Parents.size() != 1) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30547: [clang-tidy] Forwarding reference overload in constructors
leanil updated this revision to Diff 94028. leanil added a comment. fix new lines Repository: rL LLVM https://reviews.llvm.org/D30547 Files: clang-tidy/misc/CMakeLists.txt clang-tidy/misc/ForwardingReferenceOverloadCheck.cpp clang-tidy/misc/ForwardingReferenceOverloadCheck.h clang-tidy/misc/MiscTidyModule.cpp docs/ReleaseNotes.rst docs/clang-tidy/checks/list.rst docs/clang-tidy/checks/misc-forwarding-reference-overload.rst test/clang-tidy/misc-forwarding-reference-overload.cpp Index: test/clang-tidy/misc-forwarding-reference-overload.cpp === --- /dev/null +++ test/clang-tidy/misc-forwarding-reference-overload.cpp @@ -0,0 +1,139 @@ +// RUN: %check_clang_tidy %s misc-forwarding-reference-overload %t + +namespace std { +template +struct enable_if {}; + +template +struct enable_if { typedef T type; }; + +template +using enable_if_t = typename enable_if::type; + +template +struct enable_if_nice { typedef T type; }; +} + +namespace foo { +template +struct enable_if { typedef T type; }; +} + +template +constexpr bool just_true = true; + +class Test1 { +public: + template + Test1(T &&n); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor accepting a forwarding reference can hide the copy and move constructors [misc-forwarding-reference-overload] + + template + Test1(T &&n, int i = 5, ...); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor accepting a forwarding reference can hide the copy and move constructors [misc-forwarding-reference-overload] + + template ::type> + Test1(T &&n); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor accepting a forwarding reference can hide the copy and move constructors [misc-forwarding-reference-overload] + + template + Test1(T &&n, typename foo::enable_if::type i = 5, ...); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor accepting a forwarding reference can hide the copy and move constructors [misc-forwarding-reference-overload] + + Test1(const Test1 &other) {} + // CHECK-MESSAGES: :[[@LINE-1]]:3: note: copy constructor declared here + + Test1(Test1 &other) {} + // CHECK-MESSAGES: :[[@LINE-1]]:3: note: copy constructor declared here + + Test1(Test1 &&other) {} + // CHECK-MESSAGES: :[[@LINE-1]]:3: note: move constructor declared here +}; + +template +class Test2 { +public: + // Two parameters without default value, can't act as copy / move constructor. + template + Test2(T &&n, V &&m, int i = 5, ...); + + // Guarded with enable_if. + template + Test2(T &&n, int i = 5, std::enable_if_t a = 5, ...); + + // Guarded with enable_if. + template ::type &> + Test2(T &&n); + + // Guarded with enable_if. + template + Test2(T &&n, typename std::enable_if>::type **a = nullptr); + + // Guarded with enable_if. + template > *&&> + Test2(T &&n, double d = 0.0); + + // Not a forwarding reference parameter. + template + Test2(const T &&n); + + // Not a forwarding reference parameter. + Test2(int &&x); + + // Two parameters without default value, can't act as copy / move constructor. + template + Test2(T &&n, int x); + + // Not a forwarding reference parameter. + template + Test2(U &&n); +}; + +// The copy and move constructors are both disabled. +class Test3 { +public: + template + Test3(T &&n); + + template + Test3(T &&n, int I = 5, ...); + + Test3(const Test3 &rhs) = delete; + +private: + Test3(Test3 &&rhs); +}; + +// Both the copy and the (compiler generated) move constructors can be hidden. +class Test4 { +public: + template + Test4(T &&n); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor accepting a forwarding reference can hide the copy and move constructors [misc-forwarding-reference-overload] + + Test4(const Test4 &rhs); + // CHECK-MESSAGES: :[[@LINE-1]]:3: note: copy constructor declared here +}; + +// Only the (compiler generated) copy constructor can be hidden. +class Test5 { +public: + template + Test5(T &&n); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor accepting a forwarding reference can hide the copy constructor [misc-forwarding-reference-overload] + + Test5(Test5 &&rhs) = delete; +}; + +// Only the move constructor can be hidden. +class Test6 { +public: + template + Test6(T &&n); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor accepting a forwarding reference can hide the move constructor [misc-forwarding-reference-overload] + + Test6(Test6 &&rhs); + // CHECK-MESSAGES: :[[@LINE-1]]:3: note: move constructor declared here +private: + Test6(const Test6 &rhs); +}; Index: docs/clang-tidy/checks/misc-forwarding-reference-overload.rst === --- /dev/null +++ docs/clang-tidy/checks/misc-forwarding-reference-overload.rst @@ -0,0 +1,49 @@ +.. title:: clang-tidy - misc-forwarding-reference-overload + +misc-forwarding-reference-overload +== + +The check looks for p
[PATCH] D31401: [clangd] Extract FsPath from file:// uri
krasimir added inline comments. Comment at: clangd/ASTManager.cpp:166 tooling::CompilationDatabase * ASTManager::getOrCreateCompilationDatabaseForFile(StringRef Uri) { auto &I = CompilationDatabases[Uri]; I think we should rename the `Uri` parameter here to `File`. Comment at: clangd/ASTManager.cpp:178 std::unique_ptr ASTManager::createASTUnitForFile(StringRef Uri, const DocumentStore &Docs) { tooling::CompilationDatabase *CDB = I think we should rename the `Uri` parameter here to `File`. Comment at: clangd/Protocol.cpp:61 if (KeyValue == "uri") { - Result.uri = Value->getValue(Storage); + Result.uri = Uri::parse(Value->getValue(Storage)); } else if (KeyValue == "version") { Hm, seems to me that here the uri should be kept as-is and the clients of `Result.uri` should convert it to file when appropriate. Otherwise it's confusing. Comment at: clangd/Protocol.cpp:167 if (KeyValue == "uri") { - Result.uri = Value->getValue(Storage); + Result.uri = Uri::parse(Value->getValue(Storage)); } else if (KeyValue == "languageId") { Same thing: I think that the clients should be responsible of converting `Result.uri` to a filename. Comment at: clangd/Protocol.h:32 +struct Uri { + static std::string parse(llvm::StringRef uri); It's a little confusing: the `parse` method turns an `uri` to a `file` and the `unparse` method does the opposite. Maybe we should use more descriptive names, like `uriToFile` and `fileToUri`. This does not seem to be inconsistent with the rest of the protocol since the protocol only cares about uri-s, and file-s are an implementation detail of clangd I guess. Comment at: clangd/clients/clangd-vscode/src/extension.ts:28 +uriConverters: { +// FIXME: implement percent decoding in clangd +code2Protocol: (uri: vscode.Uri) : string => uri.toString(true), By the way, what does this do? I'm not a typescript vs code guru. https://reviews.llvm.org/D31401 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31594: [OpenCL] Enables passing sampler initializer to function argument
echuraev updated this revision to Diff 94032. echuraev marked an inline comment as done. https://reviews.llvm.org/D31594 Files: lib/Sema/SemaInit.cpp test/CodeGenOpenCL/sampler.cl test/SemaOpenCL/sampler_t.cl Index: test/SemaOpenCL/sampler_t.cl === --- test/SemaOpenCL/sampler_t.cl +++ test/SemaOpenCL/sampler_t.cl @@ -30,7 +30,7 @@ constant sampler_t glb_smp9 = 0x1LL; // expected-error{{sampler_t initialization requires 32-bit integer, not 'long long'}} -void foo(sampler_t); +void foo(sampler_t); // expected-note{{passing argument to parameter here}} constant struct sampler_s { sampler_t smp; // expected-error{{the 'sampler_t' type cannot be used to declare a structure or union field}} @@ -65,7 +65,8 @@ foo(const_smp5); foo(const_smp6); foo(argsmp); - foo(5); // expected-error{{sampler_t variable required - got 'int'}} + foo(5); + foo(5.0f); // expected-error {{passing 'float' to parameter of incompatible type 'sampler_t'}} sampler_t sa[] = {argsmp, const_smp}; // expected-error {{array of 'sampler_t' type is invalid in OpenCL}} foo(sa[0]); foo(bad()); Index: test/CodeGenOpenCL/sampler.cl === --- test/CodeGenOpenCL/sampler.cl +++ test/CodeGenOpenCL/sampler.cl @@ -54,4 +54,8 @@ fnc4smp(smp_par); // CHECK: [[SAMP:%[0-9]+]] = load %opencl.sampler_t addrspace(2)*, %opencl.sampler_t addrspace(2)** [[smp_par_ptr]] // CHECK: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]]) + + fnc4smp(5); + // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 5) + // CHECK: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]]) } Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -7174,7 +7174,7 @@ QualType SourceType = Init->getType(); // Case 1 if (Entity.isParameterKind()) { -if (!SourceType->isSamplerT()) { +if (!SourceType->isSamplerT() && !SourceType->isIntegerType()) { S.Diag(Kind.getLocation(), diag::err_sampler_argument_required) << SourceType; break; Index: test/SemaOpenCL/sampler_t.cl === --- test/SemaOpenCL/sampler_t.cl +++ test/SemaOpenCL/sampler_t.cl @@ -30,7 +30,7 @@ constant sampler_t glb_smp9 = 0x1LL; // expected-error{{sampler_t initialization requires 32-bit integer, not 'long long'}} -void foo(sampler_t); +void foo(sampler_t); // expected-note{{passing argument to parameter here}} constant struct sampler_s { sampler_t smp; // expected-error{{the 'sampler_t' type cannot be used to declare a structure or union field}} @@ -65,7 +65,8 @@ foo(const_smp5); foo(const_smp6); foo(argsmp); - foo(5); // expected-error{{sampler_t variable required - got 'int'}} + foo(5); + foo(5.0f); // expected-error {{passing 'float' to parameter of incompatible type 'sampler_t'}} sampler_t sa[] = {argsmp, const_smp}; // expected-error {{array of 'sampler_t' type is invalid in OpenCL}} foo(sa[0]); foo(bad()); Index: test/CodeGenOpenCL/sampler.cl === --- test/CodeGenOpenCL/sampler.cl +++ test/CodeGenOpenCL/sampler.cl @@ -54,4 +54,8 @@ fnc4smp(smp_par); // CHECK: [[SAMP:%[0-9]+]] = load %opencl.sampler_t addrspace(2)*, %opencl.sampler_t addrspace(2)** [[smp_par_ptr]] // CHECK: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]]) + + fnc4smp(5); + // CHECK: [[SAMP:%[0-9]+]] = call %opencl.sampler_t addrspace(2)* @__translate_sampler_initializer(i32 5) + // CHECK: call spir_func void @fnc4smp(%opencl.sampler_t addrspace(2)* [[SAMP]]) } Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -7174,7 +7174,7 @@ QualType SourceType = Init->getType(); // Case 1 if (Entity.isParameterKind()) { -if (!SourceType->isSamplerT()) { +if (!SourceType->isSamplerT() && !SourceType->isIntegerType()) { S.Diag(Kind.getLocation(), diag::err_sampler_argument_required) << SourceType; break; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r299426 - [clangd] Remove private vector fields from completion test.
Author: krasimir Date: Tue Apr 4 05:42:22 2017 New Revision: 299426 URL: http://llvm.org/viewvc/llvm-project?rev=299426&view=rev Log: [clangd] Remove private vector fields from completion test. Modified: clang-tools-extra/trunk/test/clangd/completion.test Modified: clang-tools-extra/trunk/test/clangd/completion.test URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/completion.test?rev=299426&r1=299425&r2=299426&view=diff == --- clang-tools-extra/trunk/test/clangd/completion.test (original) +++ clang-tools-extra/trunk/test/clangd/completion.test Tue Apr 4 05:42:22 2017 @@ -16,26 +16,6 @@ Content-Length: 148 # nondeterministic, so we check regardless of order. # # CHECK: {"jsonrpc":"2.0","id":1,"result":[ -# CHECK-DAG: {"label":"_M_allocate"} -# CHECK-DAG: {"label":"_M_allocate_and_copy"} -# CHECK-DAG: {"label":"_M_assign_aux"} -# CHECK-DAG: {"label":"_M_assign_dispatch"} -# CHECK-DAG: {"label":"_M_check_len"} -# CHECK-DAG: {"label":"_M_create_storage" -# CHECK-DAG: {"label":"_M_deallocate"} -# CHECK-DAG: {"label":"_M_erase_at_end"} -# CHECK-DAG: {"label":"_M_fill_assign"} -# CHECK-DAG: {"label":"_M_fill_initialize"} -# CHECK-DAG: {"label":"_M_fill_insert"} -# CHECK-DAG: {"label":"_M_get_Tp_allocator"} -# CHECK-DAG: {"label":"_M_impl"} -# CHECK-DAG: {"label":"_M_initialize_dispatch"} -# CHECK-DAG: {"label":"_M_insert_aux"} -# CHECK-DAG: {"label":"_M_insert_dispatch"} -# CHECK-DAG: {"label":"_M_range_check"} -# CHECK-DAG: {"label":"_M_range_initialize"} -# CHECK-DAG: {"label":"_M_range_insert"} -# CHECK-DAG: {"label":"_Vector_base"} # CHECK-DAG: {"label":"assign"} # CHECK-DAG: {"label":"at"} # CHECK-DAG: {"label":"back"} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30547: [clang-tidy] Forwarding reference overload in constructors
aaron.ballman added a comment. LGTM! If you need someone to commit on your behalf, let us know. I won't be able to do it this week. but I'm guessing @alexfh or someone else may be available to help (or I can get to it next week). Repository: rL LLVM https://reviews.llvm.org/D30547 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31513: [Sema] Add __is_aggregate type-trait
aaron.ballman accepted this revision. aaron.ballman added a comment. This revision is now accepted and ready to land. LGTM! https://reviews.llvm.org/D31513 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31308: [clang-tidy] new check readability-no-alternative-tokens
alexfh added inline comments. Comment at: clang-tidy/readability/OperatorsRepresentationCheck.cpp:34 + + if (const auto *B = Result.Nodes.getNodeAs("binary")) { +switch (B->getOpcode()) { Eugene.Zelenko wrote: > aaron.ballman wrote: > > alexfh wrote: > > > aaron.ballman wrote: > > > > mgehre wrote: > > > > > aaron.ballman wrote: > > > > > > alexfh wrote: > > > > > > > aaron.ballman wrote: > > > > > > > > I think this would make more sense lifted into an AST matcher > > > > > > > > -- there are bound to be a *lot* of binary operators, so > > > > > > > > letting the matcher memoize things is likely to give better > > > > > > > > performance. > > > > > > > Any reasons not to do this on the lexer level? > > > > > > Technical reasons? None. > > > > > > User-experience reasons? We wouldn't want this to be on by default > > > > > > (I don't think) and we usually don't implement off-by-default > > > > > > diagnostics in Clang. I think a case could be made for doing it in > > > > > > the Lexer if the performance is really that bad with a clang-tidy > > > > > > check and we couldn't improve it here, though. > > > > > Do I correctly understand that "doing this on lexer level" would mean > > > > > to implement this as a warning directly into clang? If yes, would it > > > > > be possible to generate fixits and have them possibly applied > > > > > automatically (as it is the case for clang-tidy)? > > > > You are correct, that means implementing it as a warning in Clang. I > > > > believe you can still generate those fixits from lexer-level > > > > diagnostics, but have not verified it. > > > > > > > > However, I don't think this diagnostic would be appropriate for Clang > > > > because it would have to be off by default. > > > Actually, I was thinking about changing this clang-tidy check to analyze > > > token stream somehow (probably by handling `PPCallbacks` to detect ranges > > > that need to be re-lexed) instead of matching the AST. I didn't intend to > > > propose a new Clang warning (but it looks like the wording was > > > misleading). > > There is some value in that -- it means we could support C, for instance. > > I'm not certain how easy or hard it would be, but suspect it's reasonable. > > However, in C, there's still the problem of the include file that > > introduces those macros. Do we have facilities to remove an include in > > clang-tidy? > Yes, it may make sense in C, but parameter for map from macro name to > operator is needed. > > Product I'm working for, with long history, had alternative operator > presentation implemented in C. Changing macro-based "alternative tokens" to the corresponding operators can also be formulated in the terms of expanding a set of macros, which should work with any LangOpts and arbitrary alternative operator names. > However, in C, there's still the problem of the include file that introduces > those macros. Sounds like a generic "remove unused includes" problem, since we need to analyze whether the header is needed for anything else. In particular, even if the use of the header is limited to the alternative representations of operators, we can't remove the include until we replace all these macros. Clang-tidy doesn't provide any support for transactional fixes and dependencies between fixes. https://reviews.llvm.org/D31308 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31667: [Sema] Extend GetSignedVectorType to deal with non ExtVector types
sdardis created this revision. This improves some error messages which would otherwise refer to ext_vector_type types in contexts where there are no such types. Factored out from https://reviews.llvm.org/D25866 at reviewer's request. https://reviews.llvm.org/D31667 Files: include/clang/Sema/Sema.h lib/Sema/SemaExpr.cpp test/Sema/vector-ops.c Index: test/Sema/vector-ops.c === --- test/Sema/vector-ops.c +++ test/Sema/vector-ops.c @@ -13,7 +13,7 @@ (void)(~v2fa); // expected-error{{invalid argument type 'v2f' (vector of 2 'float' values) to unary}} // Comparison operators - v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from 'int __attribute__((ext_vector_type(2)))' (vector of 2 'int' values)}} + v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int int' (vector of 2 'int' values)}} v2sa = (v2ua==v2sa); // Arrays Index: lib/Sema/SemaExpr.cpp === --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -9711,24 +9711,45 @@ return InvalidOperands(Loc, LHS, RHS); } - -// Return a signed type that is of identical size and number of elements. -// For floating point vectors, return an integer type of identical size -// and number of elements. -QualType Sema::GetSignedVectorType(QualType V) { +// Return a signed ext_vector type that is of identical size and number of +// elements. For floating point vectors, return an integer type of identical +// size and number of elements. In the non ext_vector case, search from the +// largest to the smallest to avoid cases where long long == long, where long +// gets picked over long long. +QualType Sema::GetSignedVectorType(QualType V, bool WantExtVector) { const VectorType *VTy = V->getAs(); unsigned TypeSize = Context.getTypeSize(VTy->getElementType()); - if (TypeSize == Context.getTypeSize(Context.CharTy)) -return Context.getExtVectorType(Context.CharTy, VTy->getNumElements()); - else if (TypeSize == Context.getTypeSize(Context.ShortTy)) -return Context.getExtVectorType(Context.ShortTy, VTy->getNumElements()); - else if (TypeSize == Context.getTypeSize(Context.IntTy)) -return Context.getExtVectorType(Context.IntTy, VTy->getNumElements()); + + if (WantExtVector) { +if (TypeSize == Context.getTypeSize(Context.CharTy)) + return Context.getExtVectorType(Context.CharTy, VTy->getNumElements()); +else if (TypeSize == Context.getTypeSize(Context.ShortTy)) + return Context.getExtVectorType(Context.ShortTy, VTy->getNumElements()); +else if (TypeSize == Context.getTypeSize(Context.IntTy)) + return Context.getExtVectorType(Context.IntTy, VTy->getNumElements()); +else if (TypeSize == Context.getTypeSize(Context.LongTy)) + return Context.getExtVectorType(Context.LongTy, VTy->getNumElements()); +assert(TypeSize == Context.getTypeSize(Context.LongLongTy) && + "Unhandled vector element size in vector compare"); +return Context.getExtVectorType(Context.LongLongTy, VTy->getNumElements()); + } + + if (TypeSize == Context.getTypeSize(Context.LongLongTy)) +return Context.getVectorType(Context.LongLongTy, VTy->getNumElements(), + VectorType::GenericVector); else if (TypeSize == Context.getTypeSize(Context.LongTy)) -return Context.getExtVectorType(Context.LongTy, VTy->getNumElements()); - assert(TypeSize == Context.getTypeSize(Context.LongLongTy) && +return Context.getVectorType(Context.LongTy, VTy->getNumElements(), + VectorType::GenericVector); + else if (TypeSize == Context.getTypeSize(Context.IntTy)) +return Context.getVectorType(Context.IntTy, VTy->getNumElements(), + VectorType::GenericVector); + else if (TypeSize == Context.getTypeSize(Context.ShortTy)) +return Context.getVectorType(Context.ShortTy, VTy->getNumElements(), + VectorType::GenericVector); + assert(TypeSize == Context.getTypeSize(Context.CharTy) && "Unhandled vector element size in vector compare"); - return Context.getExtVectorType(Context.LongLongTy, VTy->getNumElements()); + return Context.getVectorType(Context.CharTy, VTy->getNumElements(), + VectorType::GenericVector); } /// CheckVectorCompareOperands - vector comparisons are a clang extension that @@ -9747,6 +9768,8 @@ return vType; QualType LHSType = LHS.get()->getType(); + bool isExtVectorType = + isa(vType->getAs()) || getLangOpts().OpenCL; // If AltiVec, the comparison results in a numeric type, i.e. // bool for C++, int for C @@ -9775,9 +9798,9 @@ assert (RHS.get()->getType()->hasFloatingRepresentation());
[PATCH] D31308: [clang-tidy] new check readability-no-alternative-tokens
aaron.ballman added inline comments. Comment at: clang-tidy/readability/OperatorsRepresentationCheck.cpp:34 + + if (const auto *B = Result.Nodes.getNodeAs("binary")) { +switch (B->getOpcode()) { alexfh wrote: > Eugene.Zelenko wrote: > > aaron.ballman wrote: > > > alexfh wrote: > > > > aaron.ballman wrote: > > > > > mgehre wrote: > > > > > > aaron.ballman wrote: > > > > > > > alexfh wrote: > > > > > > > > aaron.ballman wrote: > > > > > > > > > I think this would make more sense lifted into an AST matcher > > > > > > > > > -- there are bound to be a *lot* of binary operators, so > > > > > > > > > letting the matcher memoize things is likely to give better > > > > > > > > > performance. > > > > > > > > Any reasons not to do this on the lexer level? > > > > > > > Technical reasons? None. > > > > > > > User-experience reasons? We wouldn't want this to be on by > > > > > > > default (I don't think) and we usually don't implement > > > > > > > off-by-default diagnostics in Clang. I think a case could be made > > > > > > > for doing it in the Lexer if the performance is really that bad > > > > > > > with a clang-tidy check and we couldn't improve it here, though. > > > > > > Do I correctly understand that "doing this on lexer level" would > > > > > > mean to implement this as a warning directly into clang? If yes, > > > > > > would it be possible to generate fixits and have them possibly > > > > > > applied automatically (as it is the case for clang-tidy)? > > > > > You are correct, that means implementing it as a warning in Clang. I > > > > > believe you can still generate those fixits from lexer-level > > > > > diagnostics, but have not verified it. > > > > > > > > > > However, I don't think this diagnostic would be appropriate for Clang > > > > > because it would have to be off by default. > > > > Actually, I was thinking about changing this clang-tidy check to > > > > analyze token stream somehow (probably by handling `PPCallbacks` to > > > > detect ranges that need to be re-lexed) instead of matching the AST. I > > > > didn't intend to propose a new Clang warning (but it looks like the > > > > wording was misleading). > > > There is some value in that -- it means we could support C, for instance. > > > I'm not certain how easy or hard it would be, but suspect it's > > > reasonable. However, in C, there's still the problem of the include file > > > that introduces those macros. Do we have facilities to remove an include > > > in clang-tidy? > > Yes, it may make sense in C, but parameter for map from macro name to > > operator is needed. > > > > Product I'm working for, with long history, had alternative operator > > presentation implemented in C. > Changing macro-based "alternative tokens" to the corresponding operators can > also be formulated in the terms of expanding a set of macros, which should > work with any LangOpts and arbitrary alternative operator names. > > > However, in C, there's still the problem of the include file that > > introduces those macros. > > Sounds like a generic "remove unused includes" problem, since we need to > analyze whether the header is needed for anything else. In particular, even > if the use of the header is limited to the alternative representations of > operators, we can't remove the include until we replace all these macros. > Clang-tidy doesn't provide any support for transactional fixes and > dependencies between fixes. > Sounds like a generic "remove unused includes" problem, since we need to > analyze whether the header is needed for anything else. In particular, even > if the use of the header is limited to the alternative representations of > operators, we can't remove the include until we replace all these macros. > Clang-tidy doesn't provide any support for transactional fixes and > dependencies between fixes. That's a good point. I also don't think an unused include is sufficiently awful to block this. https://reviews.llvm.org/D31308 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D25596: alpha.core.Conversion - Fix false positive for 'U32 += S16; ' expression, that is not unsafe
NoQ accepted this revision. NoQ added a comment. This revision is now accepted and ready to land. > There are several undetected "TODO: loss of precision" right now in the tests > that I would like to fix. I think it's a good idea to have `// no-warning` comments as well when testing for lack of false positives. I've a feeling that the original false positive that you've been fixing initially has disappeared from the final tests (we've got stuff with unsigned long += int, but large types behave quite differently when it comes to integral promotion). If i'm wrong, please commit :) Repository: rL LLVM https://reviews.llvm.org/D25596 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31544: Add AllowRebuild parameter to ASTUnit::Reparse()
ibronstein added inline comments. Comment at: lib/Frontend/ASTUnit.cpp:2068 +if (!AllowRebuild && !OverrideMainBuffer) + return false; + } Can we leave ASTUnit in such state? https://reviews.llvm.org/D31544 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r299431 - [X86][Clang] Converting __mm{|256|512}_movm_epi{8|16|32|64} LLVMIR call into generic intrinsics.
Author: mzuckerm Date: Tue Apr 4 08:29:53 2017 New Revision: 299431 URL: http://llvm.org/viewvc/llvm-project?rev=299431&view=rev Log: [X86][Clang] Converting __mm{|256|512}_movm_epi{8|16|32|64} LLVMIR call into generic intrinsics. This patch is a part two of two reviews, one for the clang and the other for LLVM. In this patch, I covered the clang side, by introducing the intrinsic to the front end. This is done by creating a generic replacement. Differential Revision: https://reviews.llvm.org/D31394a Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/test/CodeGen/avx512bw-builtins.c cfe/trunk/test/CodeGen/avx512dq-builtins.c cfe/trunk/test/CodeGen/avx512vlbw-builtins.c cfe/trunk/test/CodeGen/avx512vldq-builtins.c Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=299431&r1=299430&r2=299431&view=diff == --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Tue Apr 4 08:29:53 2017 @@ -7168,6 +7168,13 @@ static Value *EmitX86MinMax(CodeGenFunct return EmitX86Select(CGF, Ops[3], Res, Ops[2]); } +static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op, + llvm::Type *DstTy) { + unsigned NumberOfElements = DstTy->getVectorNumElements(); + Value *Mask = getMaskVecValue(CGF, Op, NumberOfElements); + return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2"); +} + Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E) { if (BuiltinID == X86::BI__builtin_ms_va_start || @@ -7466,6 +7473,21 @@ Value *CodeGenFunction::EmitX86BuiltinEx case X86::BI__builtin_ia32_storesd128_mask: { return EmitX86MaskedStore(*this, Ops, 16); } + + case X86::BI__builtin_ia32_cvtmask2b128: + case X86::BI__builtin_ia32_cvtmask2b256: + case X86::BI__builtin_ia32_cvtmask2b512: + case X86::BI__builtin_ia32_cvtmask2w128: + case X86::BI__builtin_ia32_cvtmask2w256: + case X86::BI__builtin_ia32_cvtmask2w512: + case X86::BI__builtin_ia32_cvtmask2d128: + case X86::BI__builtin_ia32_cvtmask2d256: + case X86::BI__builtin_ia32_cvtmask2d512: + case X86::BI__builtin_ia32_cvtmask2q128: + case X86::BI__builtin_ia32_cvtmask2q256: + case X86::BI__builtin_ia32_cvtmask2q512: +return EmitX86SExtMask(*this, Ops[0], ConvertType(E->getType())); + case X86::BI__builtin_ia32_movdqa32store128_mask: case X86::BI__builtin_ia32_movdqa64store128_mask: case X86::BI__builtin_ia32_storeaps128_mask: Modified: cfe/trunk/test/CodeGen/avx512bw-builtins.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/avx512bw-builtins.c?rev=299431&r1=299430&r2=299431&view=diff == --- cfe/trunk/test/CodeGen/avx512bw-builtins.c (original) +++ cfe/trunk/test/CodeGen/avx512bw-builtins.c Tue Apr 4 08:29:53 2017 @@ -1543,13 +1543,15 @@ __mmask64 test_mm512_movepi8_mask(__m512 __m512i test_mm512_movm_epi8(__mmask64 __A) { // CHECK-LABEL: @test_mm512_movm_epi8 - // CHECK: @llvm.x86.avx512.cvtmask2b.512 + // CHECK: %2 = bitcast i64 %1 to <64 x i1> + // CHECK: %vpmovm2.i = sext <64 x i1> %2 to <64 x i8> return _mm512_movm_epi8(__A); } __m512i test_mm512_movm_epi16(__mmask32 __A) { // CHECK-LABEL: @test_mm512_movm_epi16 - // CHECK: @llvm.x86.avx512.cvtmask2w.512 + // CHECK: %2 = bitcast i32 %1 to <32 x i1> + // CHECK: %vpmovm2.i = sext <32 x i1> %2 to <32 x i16> return _mm512_movm_epi16(__A); } Modified: cfe/trunk/test/CodeGen/avx512dq-builtins.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/avx512dq-builtins.c?rev=299431&r1=299430&r2=299431&view=diff == --- cfe/trunk/test/CodeGen/avx512dq-builtins.c (original) +++ cfe/trunk/test/CodeGen/avx512dq-builtins.c Tue Apr 4 08:29:53 2017 @@ -929,13 +929,15 @@ __mmask16 test_mm512_movepi32_mask(__m51 __m512i test_mm512_movm_epi32(__mmask16 __A) { // CHECK-LABEL: @test_mm512_movm_epi32 - // CHECK: @llvm.x86.avx512.cvtmask2d.512 + // CHECK: %2 = bitcast i16 %1 to <16 x i1> + // CHECK: %vpmovm2.i = sext <16 x i1> %2 to <16 x i32> return _mm512_movm_epi32(__A); } __m512i test_mm512_movm_epi64(__mmask8 __A) { // CHECK-LABEL: @test_mm512_movm_epi64 - // CHECK: @llvm.x86.avx512.cvtmask2q.512 + // CHECK: %2 = bitcast i8 %1 to <8 x i1> + // CHECK: %vpmovm2.i = sext <8 x i1> %2 to <8 x i64> return _mm512_movm_epi64(__A); } Modified: cfe/trunk/test/CodeGen/avx512vlbw-builtins.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/avx512vlbw-builtins.c?rev=299431&r1=299430&r2=299431&view=diff == --- cfe/trunk/test/CodeGen/avx512vlbw-builtins.c (original) +++ cfe/trunk
[PATCH] D31669: Fix lambda to block conversion in C++17 by avoiding copy elision for the lambda capture used by the created block
arphaman created this revision. The commit r288866 introduced guaranteed copy elision to C++ 17. This unfortunately broke the lambda to block conversion in C++17 (the compiler crashes when performing IRGen). This patch fixes the conversion by avoiding copy elision for the capture that captures the lambda that's used in the block created by lambda to block conversion process. Repository: rL LLVM https://reviews.llvm.org/D31669 Files: include/clang/Sema/Initialization.h lib/Sema/SemaInit.cpp lib/Sema/SemaLambda.cpp test/CodeGenObjCXX/lambda-to-block.mm Index: test/CodeGenObjCXX/lambda-to-block.mm === --- /dev/null +++ test/CodeGenObjCXX/lambda-to-block.mm @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -x objective-c++ -fblocks -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -std=c++1z -emit-llvm -o - %s | FileCheck %s + +// rdar://31385153 +// Shouldn't crash! + +void takesBlock(void (^)(void)); + +struct Copyable { + Copyable(const Copyable &x); +}; + +void hasLambda(Copyable x) { + takesBlock([x] () { }); +} +// CHECK-LABEL: __copy_helper_block_ +// CHECK: call void @_ZN8CopyableC1ERKS_ +// CHECK-LABE: __destroy_helper_block_ Index: lib/Sema/SemaLambda.cpp === --- lib/Sema/SemaLambda.cpp +++ lib/Sema/SemaLambda.cpp @@ -1649,10 +1649,10 @@ CallOperator->markUsed(Context); ExprResult Init = PerformCopyInitialization( - InitializedEntity::InitializeBlock(ConvLocation, - Src->getType(), - /*NRVO=*/false), - CurrentLocation, Src); + InitializedEntity::InitializeBlock(ConvLocation, Src->getType(), + /*NRVO=*/false, + /*IsLambdaToBlockConversion=*/true), + CurrentLocation, Src); if (!Init.isInvalid()) Init = ActOnFinishFullExpr(Init.get()); Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -3000,6 +3000,10 @@ return false; } +bool InitializedEntity::isLambdaToBlockEntity() const { + return Kind == EK_BlockElement && LocAndNRVO.IsLambdaToBlockConversionEntity; +} + unsigned InitializedEntity::dumpImpl(raw_ostream &OS) const { assert(getParent() != this); unsigned Depth = getParent() ? getParent()->dumpImpl(OS) : 0; @@ -3625,7 +3629,8 @@ if (S.getLangOpts().CPlusPlus1z && Entity.getKind() != InitializedEntity::EK_Base && Entity.getKind() != InitializedEntity::EK_Delegating && - UnwrappedArgs.size() == 1 && UnwrappedArgs[0]->isRValue() && + !Entity.isLambdaToBlockEntity() && UnwrappedArgs.size() == 1 && + UnwrappedArgs[0]->isRValue() && S.Context.hasSameUnqualifiedType(UnwrappedArgs[0]->getType(), DestType)) { // Convert qualifications if necessary. Sequence.AddQualificationConversionStep(DestType, VK_RValue); Index: include/clang/Sema/Initialization.h === --- include/clang/Sema/Initialization.h +++ include/clang/Sema/Initialization.h @@ -118,6 +118,10 @@ /// \brief Whether the entity being initialized may end up using the /// named return value optimization (NRVO). bool NRVO; + +/// \brief When Kind == EK_BlockElement, this flag determines if the entity +/// is a lambda that's captured by a block it's converted to. +bool IsLambdaToBlockConversionEntity; }; struct VD { @@ -180,11 +184,11 @@ /// function, throwing an object, performing an explicit cast, or /// initializing a parameter for which there is no declaration. InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type, -bool NRVO = false) -: Kind(Kind), Parent(nullptr), Type(Type), ManglingNumber(0) - { +bool NRVO = false, bool IsLambdaToBlockConversion = false) + : Kind(Kind), Parent(nullptr), Type(Type), ManglingNumber(0) { LocAndNRVO.Location = Loc.getRawEncoding(); LocAndNRVO.NRVO = NRVO; +LocAndNRVO.IsLambdaToBlockConversionEntity = IsLambdaToBlockConversion; } /// \brief Create the initialization entity for a member subobject. @@ -256,9 +260,11 @@ return InitializedEntity(EK_Result, ReturnLoc, Type, NRVO); } - static InitializedEntity InitializeBlock(SourceLocation BlockVarLoc, - QualType Type, bool NRVO) { -return InitializedEntity(EK_BlockElement, BlockVarLoc, Type, NRVO); + static InitializedEntity + InitializeBlock(SourceLocation BlockVarLoc, QualType Type, bool NRVO, + bool IsLambdaToBlockConversion = false) { +return InitializedEntity(EK_BlockElement, BlockVarLoc, Type, NRVO, +
[PATCH] D25866: [Sema] Support implicit scalar to vector conversions
sdardis updated this revision to Diff 94070. sdardis added a comment. Factored out the changes from https://reviews.llvm.org/D31337. https://reviews.llvm.org/D25866 Files: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Sema/SemaExpr.cpp test/Sema/vector-cast.c test/Sema/vector-g++-compat.cpp test/Sema/vector-gcc-compat.c test/Sema/zvector.c test/SemaCXX/vector-no-lax.cpp Index: test/SemaCXX/vector-no-lax.cpp === --- test/SemaCXX/vector-no-lax.cpp +++ test/SemaCXX/vector-no-lax.cpp @@ -4,6 +4,6 @@ vSInt32 foo (vUInt32 a) { vSInt32 b = { 0, 0, 0, 0 }; - b += a; // expected-error{{cannot convert between vector values}} + b += a; // expected-error{{cannot convert between vector type 'vUInt32' (vector of 4 'unsigned int' values) and vector type 'vSInt32' (vector of 4 'int' values) as implicit conversion would cause truncation}} return b; } Index: test/Sema/zvector.c === --- test/Sema/zvector.c +++ test/Sema/zvector.c @@ -326,14 +326,14 @@ bc = bc + sc2; // expected-error {{incompatible type}} bc = sc + bc2; // expected-error {{incompatible type}} - sc = sc + sc_scalar; // expected-error {{cannot convert}} - sc = sc + uc_scalar; // expected-error {{cannot convert}} - sc = sc_scalar + sc; // expected-error {{cannot convert}} - sc = uc_scalar + sc; // expected-error {{cannot convert}} - uc = uc + sc_scalar; // expected-error {{cannot convert}} - uc = uc + uc_scalar; // expected-error {{cannot convert}} - uc = sc_scalar + uc; // expected-error {{cannot convert}} - uc = uc_scalar + uc; // expected-error {{cannot convert}} + sc = sc + sc_scalar; + sc = sc + uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}} + sc = sc_scalar + sc; + sc = uc_scalar + sc; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}} + uc = uc + sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}} + uc = uc + uc_scalar; + uc = sc_scalar + uc; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}} + uc = uc_scalar + uc; ss = ss + ss2; us = us + us2; @@ -368,10 +368,10 @@ sc += sl2; // expected-error {{cannot convert}} sc += fd2; // expected-error {{cannot convert}} - sc += sc_scalar; // expected-error {{cannot convert}} - sc += uc_scalar; // expected-error {{cannot convert}} - uc += sc_scalar; // expected-error {{cannot convert}} - uc += uc_scalar; // expected-error {{cannot convert}} + sc += sc_scalar; + sc += uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}} + uc += sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}} + uc += uc_scalar; ss += ss2; us += us2; Index: test/Sema/vector-gcc-compat.c === --- /dev/null +++ test/Sema/vector-gcc-compat.c @@ -0,0 +1,335 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything + +// Test the compatibility of clang's vector extensions with gcc's vector +// extensions for C. Notably &&, ||, ?: and ! are not available. +typedef long long v2i64 __attribute__((vector_size(16))); +typedef int v2i32 __attribute__((vector_size(8))); +typedef short v2i16 __attribute__((vector_size(4))); +typedef char v2i8 __attribute__((vector_size(2))); + +typedef unsigned long long v2u64 __attribute__((vector_size(16))); +typedef unsigned int v2u32 __attribute__((vector_size(8))); +typedef unsigned short v2u16 __attribute__((vector_size(4))); +typedef unsigned char v2u8 __attribute__((vector_size(2))); + +typedef float v4f32 __attribute__((vector_size(16))); +typedef double v2f64 __attribute__((vector_size(16))); +typedef double v4f64 __attribute__((vector_size(32))); +typedef int v4i32 __attribute((vector_size(16))); + +void arithmeticTest(void); +void logicTest(void); +void comparisonTest(void); +void floatTestSignedType(char a, short b, int c, long long d); +void floatTestUnsignedType(unsigned char a, unsigned short b, unsigned int c, + unsigned long long d); +void floatTestConstant(void); +void intTestType(char a, short b, int c, long long d); +void intTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c, + unsigned long long d); +void
[PATCH] D31168: Set FMF for -ffp-contract=fast
aaron.ballman added a comment. LGTM. but you should wait for someone more familiar with this part of codegen before committing. https://reviews.llvm.org/D31168 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31594: [OpenCL] Enables passing sampler initializer to function argument
yaxunl added a comment. LGTM. Thanks. https://reviews.llvm.org/D31594 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31178: [libcxxabi] Fix exception address alignment test for EHABI
rmaprath updated this revision to Diff 94074. rmaprath added a comment. Herald added a subscriber: mgorny. Addressed review comments from @EricWF . https://reviews.llvm.org/D31178 Files: CMakeLists.txt test/libcxxabi/test/config.py test/lit.site.cfg.in test/test_exception_address_alignment.pass.cpp Index: test/test_exception_address_alignment.pass.cpp === --- test/test_exception_address_alignment.pass.cpp +++ test/test_exception_address_alignment.pass.cpp @@ -15,8 +15,8 @@ // working around this failure. // XFAIL: darwin && libcxxabi-has-system-unwinder -// Test that the address of the exception object is properly aligned to the -// largest supported alignment for the system. +// Test that the address of the exception object is properly aligned as required +// by the relevant ABI #include #include @@ -24,7 +24,16 @@ #include struct __attribute__((aligned)) AlignedType {}; -static_assert(alignof(AlignedType) == alignof(_Unwind_Exception), + +// EHABI : 8-byte aligned +// Itanium: Largest supported alignment for the system +#if defined(_LIBUNWIND_ARM_EHABI) +# define EXPECTED_ALIGNMENT 8 +#else +# define EXPECTED_ALIGNMENT alignof(AlignedType) +#endif + +static_assert(alignof(_Unwind_Exception) == EXPECTED_ALIGNMENT, "_Unwind_Exception is incorrectly aligned. This test is expected to fail"); struct MinAligned { }; @@ -35,7 +44,7 @@ try { throw MinAligned{}; } catch (MinAligned const& ref) { - assert(reinterpret_cast(&ref) % alignof(AlignedType) == 0); + assert(reinterpret_cast(&ref) % EXPECTED_ALIGNMENT == 0); } } } Index: test/lit.site.cfg.in === --- test/lit.site.cfg.in +++ test/lit.site.cfg.in @@ -6,6 +6,7 @@ config.abi_library_path = "@LIBCXXABI_LIBRARY_DIR@" config.libcxx_src_root = "@LIBCXXABI_LIBCXX_PATH@" config.cxx_headers = "@LIBCXXABI_LIBCXX_INCLUDES@" +config.libunwind_headers= "@LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL@" config.cxx_library_root = "@LIBCXXABI_LIBCXX_LIBRARY_PATH@" config.llvm_unwinder= "@LIBCXXABI_USE_LLVM_UNWINDER@" config.enable_threads = "@LIBCXXABI_ENABLE_THREADS@" Index: test/libcxxabi/test/config.py === --- test/libcxxabi/test/config.py +++ test/libcxxabi/test/config.py @@ -84,6 +84,13 @@ % libcxxabi_headers) self.cxx.compile_flags += ['-I' + libcxxabi_headers] +libunwind_headers = self.get_lit_conf('libunwind_headers', None) +if self.get_lit_bool('llvm_unwinder', False) and libunwind_headers: +if not os.path.isdir(libunwind_headers): +self.lit_config.fatal("libunwind_headers='%s' is not a directory." + % libunwind_headers) +self.cxx.compile_flags += ['-I' + libunwind_headers] + def configure_compile_flags_exceptions(self): pass Index: CMakeLists.txt === --- CMakeLists.txt +++ CMakeLists.txt @@ -502,9 +502,14 @@ set(LIBCXXABI_LIBUNWIND_SOURCES "") endif() - if (NOT LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL STREQUAL "LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL-NOTFOUND") + if (LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL STREQUAL "LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL-NOTFOUND") +set(LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL "") + endif() + + if (NOT LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL STREQUAL "") include_directories("${LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL}") endif() + if (NOT LIBCXXABI_LIBUNWIND_SOURCES STREQUAL "") include_directories("${LIBCXXABI_LIBUNWIND_SOURCES}") endif() Index: test/test_exception_address_alignment.pass.cpp === --- test/test_exception_address_alignment.pass.cpp +++ test/test_exception_address_alignment.pass.cpp @@ -15,8 +15,8 @@ // working around this failure. // XFAIL: darwin && libcxxabi-has-system-unwinder -// Test that the address of the exception object is properly aligned to the -// largest supported alignment for the system. +// Test that the address of the exception object is properly aligned as required +// by the relevant ABI #include #include @@ -24,7 +24,16 @@ #include struct __attribute__((aligned)) AlignedType {}; -static_assert(alignof(AlignedType) == alignof(_Unwind_Exception), + +// EHABI : 8-byte aligned +// Itanium: Largest supported alignment for the system +#if defined(_LIBUNWIND_ARM_EHABI) +# define EXPECTED_ALIGNMENT 8 +#else +# define EXPECTED_ALIGNMENT alignof(AlignedType) +#endif + +static_assert(alignof(_Unwind_Exception) == EXPECTED_ALIGNMENT, "_Unwind_Exception is incorrectly aligned. This test is expected to fail"); struct MinAligned { }; @@ -35,7 +44,7 @@ t
[libcxxabi] r299435 - Fix exception address alignment test for EHABI
Author: asiri Date: Tue Apr 4 09:03:54 2017 New Revision: 299435 URL: http://llvm.org/viewvc/llvm-project?rev=299435&view=rev Log: Fix exception address alignment test for EHABI This test fails on ARM bare-metal targets because it assumes the Itanium ABI, whereas EHABI requires the exception address to be 8-byte aligned. I was a bit puzzled at first because this should've failed on the public arm-linux builder too. I think the reason it passes there is because we don't include libunwind headers in the include path when running the libcxxabi tests, so the system unwind.h gets picked up. Reviewers: rengolin, EricWF Differential revision: https://reviews.llvm.org/D31178 Modified: libcxxabi/trunk/CMakeLists.txt libcxxabi/trunk/test/libcxxabi/test/config.py libcxxabi/trunk/test/lit.site.cfg.in libcxxabi/trunk/test/test_exception_address_alignment.pass.cpp Modified: libcxxabi/trunk/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/CMakeLists.txt?rev=299435&r1=299434&r2=299435&view=diff == --- libcxxabi/trunk/CMakeLists.txt (original) +++ libcxxabi/trunk/CMakeLists.txt Tue Apr 4 09:03:54 2017 @@ -502,9 +502,14 @@ if (LIBCXXABI_USE_LLVM_UNWINDER OR LLVM_ set(LIBCXXABI_LIBUNWIND_SOURCES "") endif() - if (NOT LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL STREQUAL "LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL-NOTFOUND") + if (LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL STREQUAL "LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL-NOTFOUND") +set(LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL "") + endif() + + if (NOT LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL STREQUAL "") include_directories("${LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL}") endif() + if (NOT LIBCXXABI_LIBUNWIND_SOURCES STREQUAL "") include_directories("${LIBCXXABI_LIBUNWIND_SOURCES}") endif() Modified: libcxxabi/trunk/test/libcxxabi/test/config.py URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/libcxxabi/test/config.py?rev=299435&r1=299434&r2=299435&view=diff == --- libcxxabi/trunk/test/libcxxabi/test/config.py (original) +++ libcxxabi/trunk/test/libcxxabi/test/config.py Tue Apr 4 09:03:54 2017 @@ -84,6 +84,13 @@ class Configuration(LibcxxConfiguration) % libcxxabi_headers) self.cxx.compile_flags += ['-I' + libcxxabi_headers] +libunwind_headers = self.get_lit_conf('libunwind_headers', None) +if self.get_lit_bool('llvm_unwinder', False) and libunwind_headers: +if not os.path.isdir(libunwind_headers): +self.lit_config.fatal("libunwind_headers='%s' is not a directory." + % libunwind_headers) +self.cxx.compile_flags += ['-I' + libunwind_headers] + def configure_compile_flags_exceptions(self): pass Modified: libcxxabi/trunk/test/lit.site.cfg.in URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/lit.site.cfg.in?rev=299435&r1=299434&r2=299435&view=diff == --- libcxxabi/trunk/test/lit.site.cfg.in (original) +++ libcxxabi/trunk/test/lit.site.cfg.in Tue Apr 4 09:03:54 2017 @@ -6,6 +6,7 @@ config.libcxxabi_obj_root = "@LIBC config.abi_library_path = "@LIBCXXABI_LIBRARY_DIR@" config.libcxx_src_root = "@LIBCXXABI_LIBCXX_PATH@" config.cxx_headers = "@LIBCXXABI_LIBCXX_INCLUDES@" +config.libunwind_headers= "@LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL@" config.cxx_library_root = "@LIBCXXABI_LIBCXX_LIBRARY_PATH@" config.llvm_unwinder= "@LIBCXXABI_USE_LLVM_UNWINDER@" config.enable_threads = "@LIBCXXABI_ENABLE_THREADS@" Modified: libcxxabi/trunk/test/test_exception_address_alignment.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_exception_address_alignment.pass.cpp?rev=299435&r1=299434&r2=299435&view=diff == --- libcxxabi/trunk/test/test_exception_address_alignment.pass.cpp (original) +++ libcxxabi/trunk/test/test_exception_address_alignment.pass.cpp Tue Apr 4 09:03:54 2017 @@ -15,8 +15,8 @@ // working around this failure. // XFAIL: darwin && libcxxabi-has-system-unwinder -// Test that the address of the exception object is properly aligned to the -// largest supported alignment for the system. +// Test that the address of the exception object is properly aligned as required +// by the relevant ABI #include #include @@ -24,7 +24,16 @@ #include struct __attribute__((aligned)) AlignedType {}; -static_assert(alignof(AlignedType) == alignof(_Unwind_Exception), + +// EHABI : 8-byte aligned +// Itanium: Largest supported alignment for the system +#if defined(_LIBUNWIND_ARM_EHABI) +# define EXPECTED_ALIGNMENT 8 +#else +# define EXPECTED_ALI
[PATCH] D31178: [libcxxabi] Fix exception address alignment test for EHABI
This revision was automatically updated to reflect the committed changes. Closed by commit rL299435: Fix exception address alignment test for EHABI (authored by asiri). Changed prior to commit: https://reviews.llvm.org/D31178?vs=94074&id=94075#toc Repository: rL LLVM https://reviews.llvm.org/D31178 Files: libcxxabi/trunk/CMakeLists.txt libcxxabi/trunk/test/libcxxabi/test/config.py libcxxabi/trunk/test/lit.site.cfg.in libcxxabi/trunk/test/test_exception_address_alignment.pass.cpp Index: libcxxabi/trunk/test/lit.site.cfg.in === --- libcxxabi/trunk/test/lit.site.cfg.in +++ libcxxabi/trunk/test/lit.site.cfg.in @@ -6,6 +6,7 @@ config.abi_library_path = "@LIBCXXABI_LIBRARY_DIR@" config.libcxx_src_root = "@LIBCXXABI_LIBCXX_PATH@" config.cxx_headers = "@LIBCXXABI_LIBCXX_INCLUDES@" +config.libunwind_headers= "@LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL@" config.cxx_library_root = "@LIBCXXABI_LIBCXX_LIBRARY_PATH@" config.llvm_unwinder= "@LIBCXXABI_USE_LLVM_UNWINDER@" config.enable_threads = "@LIBCXXABI_ENABLE_THREADS@" Index: libcxxabi/trunk/test/test_exception_address_alignment.pass.cpp === --- libcxxabi/trunk/test/test_exception_address_alignment.pass.cpp +++ libcxxabi/trunk/test/test_exception_address_alignment.pass.cpp @@ -15,16 +15,25 @@ // working around this failure. // XFAIL: darwin && libcxxabi-has-system-unwinder -// Test that the address of the exception object is properly aligned to the -// largest supported alignment for the system. +// Test that the address of the exception object is properly aligned as required +// by the relevant ABI #include #include #include struct __attribute__((aligned)) AlignedType {}; -static_assert(alignof(AlignedType) == alignof(_Unwind_Exception), + +// EHABI : 8-byte aligned +// Itanium: Largest supported alignment for the system +#if defined(_LIBUNWIND_ARM_EHABI) +# define EXPECTED_ALIGNMENT 8 +#else +# define EXPECTED_ALIGNMENT alignof(AlignedType) +#endif + +static_assert(alignof(_Unwind_Exception) == EXPECTED_ALIGNMENT, "_Unwind_Exception is incorrectly aligned. This test is expected to fail"); struct MinAligned { }; @@ -35,7 +44,7 @@ try { throw MinAligned{}; } catch (MinAligned const& ref) { - assert(reinterpret_cast(&ref) % alignof(AlignedType) == 0); + assert(reinterpret_cast(&ref) % EXPECTED_ALIGNMENT == 0); } } } Index: libcxxabi/trunk/test/libcxxabi/test/config.py === --- libcxxabi/trunk/test/libcxxabi/test/config.py +++ libcxxabi/trunk/test/libcxxabi/test/config.py @@ -84,6 +84,13 @@ % libcxxabi_headers) self.cxx.compile_flags += ['-I' + libcxxabi_headers] +libunwind_headers = self.get_lit_conf('libunwind_headers', None) +if self.get_lit_bool('llvm_unwinder', False) and libunwind_headers: +if not os.path.isdir(libunwind_headers): +self.lit_config.fatal("libunwind_headers='%s' is not a directory." + % libunwind_headers) +self.cxx.compile_flags += ['-I' + libunwind_headers] + def configure_compile_flags_exceptions(self): pass Index: libcxxabi/trunk/CMakeLists.txt === --- libcxxabi/trunk/CMakeLists.txt +++ libcxxabi/trunk/CMakeLists.txt @@ -502,9 +502,14 @@ set(LIBCXXABI_LIBUNWIND_SOURCES "") endif() - if (NOT LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL STREQUAL "LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL-NOTFOUND") + if (LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL STREQUAL "LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL-NOTFOUND") +set(LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL "") + endif() + + if (NOT LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL STREQUAL "") include_directories("${LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL}") endif() + if (NOT LIBCXXABI_LIBUNWIND_SOURCES STREQUAL "") include_directories("${LIBCXXABI_LIBUNWIND_SOURCES}") endif() Index: libcxxabi/trunk/test/lit.site.cfg.in === --- libcxxabi/trunk/test/lit.site.cfg.in +++ libcxxabi/trunk/test/lit.site.cfg.in @@ -6,6 +6,7 @@ config.abi_library_path = "@LIBCXXABI_LIBRARY_DIR@" config.libcxx_src_root = "@LIBCXXABI_LIBCXX_PATH@" config.cxx_headers = "@LIBCXXABI_LIBCXX_INCLUDES@" +config.libunwind_headers= "@LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL@" config.cxx_library_root = "@LIBCXXABI_LIBCXX_LIBRARY_PATH@" config.llvm_unwinder= "@LIBCXXABI_USE_LLVM_UNWINDER@" config.enable_threads = "@LIBCXXABI_ENABLE_THREADS@" Index: libcxxabi/trunk/test/test_exception_address_alignment.pass.cpp =
[PATCH] D27918: [analyzer] OStreamChecker
NoQ added a comment. Hello, Sorry again for the delays, thank you for your patience. Your checker is in good shape, very well-structured and easy to follow, you definitely know your stuff, and my comments here are relatively minor. Are you planning on making more varied warning messages, eg. specifying which format modifiers are forgotten, and where in the code they were previously set? The latter could be done by using the "bug reporter visitor" mechanism. I'm sure we can at the very least eventually land this checker into the `optin` package, which is the new package for warnings that aren't on by default, but are advised to be turned on by the users if the codebase intends to use certain language or API features or contracts (unlike the `alpha` package which is for checkers undergoing development to be ultimately moved out of alpha). For moving out of alpha, i think the work on the warning messages needs to be done, and the checker needs to be tested on a large codebase to make sure that the false positive rate is low (i guess you already did it), and that's pretty much it :) On a side note, i've been recently thinking of making `optin` checkers more visible to the `scan-build` users, eg. mentioning in the log that certain checks may be worth enabling. Comment at: lib/StaticAnalyzer/Checkers/OStreamFormatChecker.cpp:263-282 + mutable IdentifierInfo *II_BasicOstream, *II_Flags, *II_Setf, *II_Unsetf, + *II_Setiosflags, *II_Resetiosflags, *II_Precision, *II_SetPrecision, + *II_BaseField, *II_Hex, *II_Dec, *II_Oct, *II_AdjustField, *II_Left, + *II_Right, *II_Internal, *II_BoolAlpha, *II_NoBoolAlpha, *II_ShowPos, + *II_NoShowPos, *II_ShowBase, *II_NoShowBase, *II_UpperCase, + *II_NoUpperCase, *II_ShowPoint, *II_NoShowPoint, *II_FloatField, + *II_Fixed, *II_Scientific; If you ever want to extend the `CallDescription` class to cover your use case, please let us know :) While most of these aren't functions, the approach used in this class could be used here as well - making initialization code shorter. Comment at: lib/StaticAnalyzer/Checkers/OStreamFormatChecker.cpp:387 + +static Optional tryEvaluateAsInt(const Expr *E, ProgramStateRef S, + CheckerContext C) { I think you should use `SimpleSValBuilder::getKnownValue()`. The `EvaluateAsInt` part doesn't add much because the analyzer's engine should already be more powerful than that. On the other hand, the `ConstraintManager::getSymVal()` thing, which is already done in `SimpleSValBuilder::getKnownValue()`, may be useful. Comment at: lib/StaticAnalyzer/Checkers/OStreamFormatChecker.cpp:403 + + return Optional(); +} By the way, there's the `None` thing that represents any empty optional. Comment at: lib/StaticAnalyzer/Checkers/OStreamFormatChecker.cpp:513 + +bool OStreamFormatChecker::evalCall(const CallExpr *CE, +CheckerContext &C) const { One of the practical differences between `checkPostCall` and `evalCall` is that in the latter you have full control over the function execution, including invalidations that the call causes. Your code not only sets the return value, but also removes invalidations that normally happen. Like, normally when an unknown function is called, it is either inlined and therefore modeled directly, or destroys all information about any global variables or heap memory that it might have touched. By implementing `evalCall`, you are saying that the only effect of calling `operator<<()` on a `basic_ostream` is returning the first argument lvalue, and nothing else happens; inlining is suppressed, invalidation is suppressed. I'm not sure if it's a good thing. On one hand, this is not entirely true, because the operator changes the internal state of the stream and maybe of some global stuff inside the standard library. On the other hand, it is unlikely to matter in practice, as far as i can see. Would it undermine any of your efforts here if you add a manual invalidation of the stream object and of the `GlobalSystemSpaceRegion` memory space (you could construct a temporary `CallEvent` and call one of its methods if it turns out to be easier)? I'm not exactly in favor of turning this into `checkPostCall()` because binding expressions in that callback may cause hard-to-notice conflicts across multiple checkers. Some checkers may even take the old value before it's replaced. For `evalCall()` we at least have an assert. If you intend to keep the return value as the only effect, there's option of making a synthesized body in our body farm, which is even better at avoiding inter-checker conflicts. Body farms were created for that specific purpose, even though they also have their drawbacks (sometimes `evalCall` is more flexible than anything we could synth
[PATCH] D28771: [Analyzer] Various fixes for the IteratorPastEnd checker
NoQ added a comment. Hello, Because i couldn't reproduce the loc-nonloc problem on my standard library, could you share a preprocessed file with the issue? I'm really curious at what's going on here, and it's the only issue remaining, so maybe we could squash it together. https://reviews.llvm.org/D28771 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31168: Set FMF for -ffp-contract=fast
anemet added a comment. Thanks, Aaron! @rjmccall, does it look good to you too? https://reviews.llvm.org/D31168 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r299440 - [clangd] Fix completion test to not depend on the standard library
Author: krasimir Date: Tue Apr 4 10:08:42 2017 New Revision: 299440 URL: http://llvm.org/viewvc/llvm-project?rev=299440&view=rev Log: [clangd] Fix completion test to not depend on the standard library Modified: clang-tools-extra/trunk/test/clangd/completion.test Modified: clang-tools-extra/trunk/test/clangd/completion.test URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clangd/completion.test?rev=299440&r1=299439&r2=299440&view=diff == --- clang-tools-extra/trunk/test/clangd/completion.test (original) +++ clang-tools-extra/trunk/test/clangd/completion.test Tue Apr 4 10:08:42 2017 @@ -5,44 +5,20 @@ Content-Length: 125 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} -Content-Length: 208 +Content-Length: 211 -{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"#include \nint main() {\n std::vector v;\n v.\n}\n"}}} +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"struct fake { int a, bb, ccc; };\nint main() {\n fake f;\n f.\n}\n"}}} Content-Length: 148 -{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":4}}} +{"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":5}}} # The order of results returned by ASTUnit CodeComplete seems to be # nondeterministic, so we check regardless of order. # # CHECK: {"jsonrpc":"2.0","id":1,"result":[ -# CHECK-DAG: {"label":"assign"} -# CHECK-DAG: {"label":"at"} -# CHECK-DAG: {"label":"back"} -# CHECK-DAG: {"label":"begin"} -# CHECK-DAG: {"label":"capacity"} -# CHECK-DAG: {"label":"clear"} -# CHECK-DAG: {"label":"data"} -# CHECK-DAG: {"label":"empty"} -# CHECK-DAG: {"label":"end"} -# CHECK-DAG: {"label":"erase"} -# CHECK-DAG: {"label":"front"} -# CHECK-DAG: {"label":"get_allocator"} -# CHECK-DAG: {"label":"insert"} -# CHECK-DAG: {"label":"max_size"} -# CHECK-DAG: {"label":"operator="} -# CHECK-DAG: {"label":"operator[]"} -# CHECK-DAG: {"label":"pop_back"} -# CHECK-DAG: {"label":"push_back"} -# CHECK-DAG: {"label":"rbegin"} -# CHECK-DAG: {"label":"rend"} -# CHECK-DAG: {"label":"reserve"} -# CHECK-DAG: {"label":"resize"} -# CHECK-DAG: {"label":"size"} -# CHECK-DAG: {"label":"swap"} -# CHECK-DAG: {"label":"vector"} -# CHECK-DAG: {"label":"~_Vector_base"} -# CHECK-DAG: {"label":"~vector"} +# CHECK-DAG: {"label":"a"} +# CHECK-DAG: {"label":"bb"} +# CHECK-DAG: {"label":"ccc"} # CHECK: ]} Content-Length: 44 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30295: [analyzer] clarify undef shift result when shift count is negative or exceeds the bit width
NoQ added a comment. Hello, sorry for your having to wait on me. The implementation looks good, i'm only having a couple of public API concerns. Comment at: include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h:46-49 +bool isExprResultConformsComparisonRule(CheckerContext &C, +BinaryOperatorKind CompRule, +const Expr *LHSExpr, const SVal RHSVal); +bool isGreaterEqual(CheckerContext &C, const Expr *E, unsigned long long Val); Because you are making these functions public, i think it's worth it to make it obvious what they do without looking at the particular checker code. Comments are definitely worth it. I think function names could be worded better; i suggest `exprComparesTo(const Expr *LHSExpr, BinaryOperatorKind ComparisonOp, SVal RHSVal, CheckerContext &C);` and `isGreaterOrEqual(...)`; i'm personally fond of having CheckerContext at the back because that's where we have it in checker callbacks, but that's not important. Comment at: lib/StaticAnalyzer/Core/CheckerHelpers.cpp:101 +const SVal RHSVal) { + ProgramStateRef State = C.getState(); + I believe it is enough to pass only `State` to this function. `SValBuilder` and `ConstraintManager` objects can be obtained from the state's `ProgramStateManager`. The good thing about requiring only `State` is that we'd be able to use these functions in checker callbacks that don't provide the `CheckerContext` object, eg. `checkEndAnalysis` or `checkRegionChanges`. Repository: rL LLVM https://reviews.llvm.org/D30295 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31669: Fix lambda to block conversion in C++17 by avoiding copy elision for the lambda capture used by the created block
aprantl added inline comments. Comment at: include/clang/Sema/Initialization.h:122 + +/// \brief When Kind == EK_BlockElement, this flag determines if the entity +/// is a lambda that's captured by a block it's converted to. No need to use \brief any more. LLVM uses autobrief. Repository: rL LLVM https://reviews.llvm.org/D31669 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D23418: [analyzer] Added a reusable constraint system to the CloneDetector
NoQ accepted this revision. NoQ added a comment. Yay, i think this is good to go. Sorry again for being slow>< I guess i'd go ahead and land this patch soon. Comment at: include/clang/Analysis/CloneDetection.h:228 +/// custom constraints. +class CloneConstraint { +public: All right, now this is essentially a namespace :) https://reviews.llvm.org/D23418 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D23418: [analyzer] Added a reusable constraint system to the CloneDetector
teemperor added a comment. Change it to a namespace when merging if you prefer that :). Thanks for the review! https://reviews.llvm.org/D23418 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31594: [OpenCL] Enables passing sampler initializer to function argument
Anastasia accepted this revision. Anastasia added a comment. This revision is now accepted and ready to land. LGTM! https://reviews.llvm.org/D31594 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r299442 - Fix problem with test.
Author: mzuckerm Date: Tue Apr 4 10:44:06 2017 New Revision: 299442 URL: http://llvm.org/viewvc/llvm-project?rev=299442&view=rev Log: Fix problem with test. Modified: cfe/trunk/test/CodeGen/avx512bw-builtins.c cfe/trunk/test/CodeGen/avx512dq-builtins.c cfe/trunk/test/CodeGen/avx512vlbw-builtins.c cfe/trunk/test/CodeGen/avx512vldq-builtins.c Modified: cfe/trunk/test/CodeGen/avx512bw-builtins.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/avx512bw-builtins.c?rev=299442&r1=299441&r2=299442&view=diff == --- cfe/trunk/test/CodeGen/avx512bw-builtins.c (original) +++ cfe/trunk/test/CodeGen/avx512bw-builtins.c Tue Apr 4 10:44:06 2017 @@ -1543,15 +1543,15 @@ __mmask64 test_mm512_movepi8_mask(__m512 __m512i test_mm512_movm_epi8(__mmask64 __A) { // CHECK-LABEL: @test_mm512_movm_epi8 - // CHECK: %2 = bitcast i64 %1 to <64 x i1> - // CHECK: %vpmovm2.i = sext <64 x i1> %2 to <64 x i8> + // CHECK: %{{.*}} = bitcast i64 %{{.*}} to <64 x i1> + // CHECK: %vpmovm2.i = sext <64 x i1> %{{.*}} to <64 x i8> return _mm512_movm_epi8(__A); } __m512i test_mm512_movm_epi16(__mmask32 __A) { // CHECK-LABEL: @test_mm512_movm_epi16 - // CHECK: %2 = bitcast i32 %1 to <32 x i1> - // CHECK: %vpmovm2.i = sext <32 x i1> %2 to <32 x i16> + // CHECK: %{{.*}} = bitcast i32 %{{.*}} to <32 x i1> + // CHECK: %vpmovm2.i = sext <32 x i1> %{{.*}} to <32 x i16> return _mm512_movm_epi16(__A); } Modified: cfe/trunk/test/CodeGen/avx512dq-builtins.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/avx512dq-builtins.c?rev=299442&r1=299441&r2=299442&view=diff == --- cfe/trunk/test/CodeGen/avx512dq-builtins.c (original) +++ cfe/trunk/test/CodeGen/avx512dq-builtins.c Tue Apr 4 10:44:06 2017 @@ -929,15 +929,15 @@ __mmask16 test_mm512_movepi32_mask(__m51 __m512i test_mm512_movm_epi32(__mmask16 __A) { // CHECK-LABEL: @test_mm512_movm_epi32 - // CHECK: %2 = bitcast i16 %1 to <16 x i1> - // CHECK: %vpmovm2.i = sext <16 x i1> %2 to <16 x i32> + // CHECK: %{{.*}} = bitcast i16 %{{.*}} to <16 x i1> + // CHECK: %vpmovm2.i = sext <16 x i1> %{{.*}} to <16 x i32> return _mm512_movm_epi32(__A); } __m512i test_mm512_movm_epi64(__mmask8 __A) { // CHECK-LABEL: @test_mm512_movm_epi64 - // CHECK: %2 = bitcast i8 %1 to <8 x i1> - // CHECK: %vpmovm2.i = sext <8 x i1> %2 to <8 x i64> + // CHECK: %{{.*}} = bitcast i8 %{{.*}} to <8 x i1> + // CHECK: %vpmovm2.i = sext <8 x i1> %{{.*}} to <8 x i64> return _mm512_movm_epi64(__A); } Modified: cfe/trunk/test/CodeGen/avx512vlbw-builtins.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/avx512vlbw-builtins.c?rev=299442&r1=299441&r2=299442&view=diff == --- cfe/trunk/test/CodeGen/avx512vlbw-builtins.c (original) +++ cfe/trunk/test/CodeGen/avx512vlbw-builtins.c Tue Apr 4 10:44:06 2017 @@ -2521,29 +2521,29 @@ __mmask32 test_mm256_movepi8_mask(__m256 __m128i test_mm_movm_epi8(__mmask16 __A) { // CHECK-LABEL: @test_mm_movm_epi8 - // CHECK: %2 = bitcast i16 %1 to <16 x i1> - // CHECK: %vpmovm2.i = sext <16 x i1> %2 to <16 x i8> + // CHECK: %{{.*}} = bitcast i16 %{{.*}} to <16 x i1> + // CHECK: %vpmovm2.i = sext <16 x i1> %{{.*}} to <16 x i8> return _mm_movm_epi8(__A); } __m256i test_mm256_movm_epi8(__mmask32 __A) { // CHECK-LABEL: @test_mm256_movm_epi8 - // CHECK: %2 = bitcast i32 %1 to <32 x i1> - // CHECK: %vpmovm2.i = sext <32 x i1> %2 to <32 x i8> + // CHECK: %{{.*}} = bitcast i32 %{{.*}} to <32 x i1> + // CHECK: %vpmovm2.i = sext <32 x i1> %{{.*}} to <32 x i8> return _mm256_movm_epi8(__A); } __m128i test_mm_movm_epi16(__mmask8 __A) { // CHECK-LABEL: @test_mm_movm_epi16 - // CHECK: %2 = bitcast i8 %1 to <8 x i1> - // CHECK: %vpmovm2.i = sext <8 x i1> %2 to <8 x i16> + // CHECK: %{{.*}} = bitcast i8 %{{.*}} to <8 x i1> + // CHECK: %vpmovm2.i = sext <8 x i1> %{{.*}} to <8 x i16> return _mm_movm_epi16(__A); } __m256i test_mm256_movm_epi16(__mmask16 __A) { // CHECK-LABEL: @test_mm256_movm_epi16 - // CHECK: %2 = bitcast i16 %1 to <16 x i1> - // CHECK: %vpmovm2.i = sext <16 x i1> %2 to <16 x i16> + // CHECK: %{{.*}} = bitcast i16 %{{.*}} to <16 x i1> + // CHECK: %vpmovm2.i = sext <16 x i1> %{{.*}} to <16 x i16> return _mm256_movm_epi16(__A); } Modified: cfe/trunk/test/CodeGen/avx512vldq-builtins.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/avx512vldq-builtins.c?rev=299442&r1=299441&r2=299442&view=diff == --- cfe/trunk/test/CodeGen/avx512vldq-builtins.c (original) +++ cfe/trunk/test/CodeGen/avx512vldq-builtins.c Tue Apr 4 10:44:06 2017 @@ -865,31 +865,31 @@ __mmask8 test_mm256_movepi32_mask(__m256 __m128i test_mm_m
[PATCH] D30810: Preserve vec3 type.
Anastasia added a comment. In https://reviews.llvm.org/D30810#710069, @jaykang10 wrote: > > I believe the argument lacks numbers (or at least you have them but didn't > > mention). I didn't hear about performance results, or validation that this > > was actually tested for correctness. Small test cases prove a point, but > > can't be considered general. > > > > OTOH, it seems like this is exactly why you want the flag, to hide any > > potential issues and play with it. I'm not opposed to adding the flag if > > there's a commitment to actually get the result and change the default to > > whatever seems to be better, does that seems reasonable? > > To be honest, I did not start this discussion to get better performance for > GPU. But the goal has moved while we discussing it. I think I have showed you > the gain from AMD GPU target on previous comments. On current version of > clang/llvm, it generates one less load/store to preserve vec3 type instead of > vec4 type on GPU target. But it could cause more load/store on another > targets which have vector register because they usually expect aligned vector > load/store. It means that if we want to change default to vec3 on clang, we > need to change llvm's codegen's default legalization or backend targets need > to be modified in order to get aligned vector load/store with vec3 type. I > think It is too big change at this moment. In the future, we could move this > discussion to llvm-dev. Up to that time, as you mentioned, I would like to > hide the potential issues with vec3 type and play with it. Just to summarize. There seems to be no issue in adding this feature by a special flag considering that changing default behaviors requires changing the backend that we might consider at some later point of time. We can start a separate discussion on that. The change can be used to generate more generic and optimal IR resulting in 1/4 less instructions generated in the final binary per each load and store of vec2 types in some architectures (e.g. AMD) . I am not sure what kind of further numbers are needed and if there is any measuring infrastructure LLVM project provides for that. Considering all the above I don't feel there is any reason this can't be committed. https://reviews.llvm.org/D30810 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30810: Preserve vec3 type.
Anastasia accepted this revision. Anastasia added a comment. This revision is now accepted and ready to land. LGTM! Thanks! https://reviews.llvm.org/D30810 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30643: [OpenCL] Extended diagnostics for atomic initialization
Anastasia accepted this revision. Anastasia added a comment. This revision is now accepted and ready to land. LGTM! Thanks! https://reviews.llvm.org/D30643 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31670: [coroutines] Implement correct GRO lifetime
GorNishanov created this revision. Herald added a subscriber: EricWF. Sema creates a declaration for gro variable as: auto $gro = $promise.get_return_object(); However, gro variable has to outlive coroutine frame and coroutine promise, but, it can only be initialized after the coroutine promise was created, thus, we split its emission in two parts: EmitGroAlloca emits an alloca and sets up the cleanups. Later when the coroutine promise is available we initialize the gro and set the flag that the cleanup is now active. https://reviews.llvm.org/D31670 Files: lib/CodeGen/CGCoroutine.cpp test/CodeGenCoroutines/coro-gro.cpp Index: test/CodeGenCoroutines/coro-gro.cpp === --- /dev/null +++ test/CodeGenCoroutines/coro-gro.cpp @@ -0,0 +1,86 @@ +// Verifies lifetime of __gro local variable +// Verify that coroutine promise and allocated memory are freed up on exception. +// RUN: %clang_cc1 -std=c++1z -fcoroutines-ts -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s -disable-llvm-passes | FileCheck %s + +namespace std::experimental { +template struct coroutine_traits; + +template struct coroutine_handle { + coroutine_handle() = default; + static coroutine_handle from_address(void *) noexcept; +}; +template <> struct coroutine_handle { + static coroutine_handle from_address(void *) noexcept; + coroutine_handle() = default; + template + coroutine_handle(coroutine_handle) noexcept; +}; +} + +struct suspend_always { + bool await_ready() noexcept; + void await_suspend(std::experimental::coroutine_handle<>) noexcept; + void await_resume() noexcept; +}; + +struct GroType { + ~GroType(); + operator int() noexcept; +}; + +template <> struct std::experimental::coroutine_traits { + struct promise_type { +GroType get_return_object() noexcept; +suspend_always initial_suspend() noexcept; +suspend_always final_suspend() noexcept; +void return_void() noexcept; +promise_type(); +~promise_type(); +void unhandled_exception() noexcept; + }; +}; + +struct Cleanup { ~Cleanup(); }; +void doSomething() noexcept; + +// CHECK: define i32 @_Z1fv( +int f() { + // CHECK: %[[RetVal:.+]] = alloca i32 + // CHECK: %[[GroActive:.+]] = alloca i1 + + // CHECK: %[[Size:.+]] = call i64 @llvm.coro.size.i64() + // CHECK: call i8* @_Znwm(i64 %[[Size]]) + // CHECK: store i1 false, i1* %[[GroActive]] + // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJiEE12promise_typeC1Ev( + // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJiEE12promise_type17get_return_objectEv( + // CHECK: store i1 true, i1* %[[GroActive]] + + Cleanup cleanup; + doSomething(); + co_return; + + // CHECK: call void @_Z11doSomethingv( + // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJiEE12promise_type11return_voidEv( + // CHECK: call void @_ZN7CleanupD1Ev( + + // Destroy promise and free the memory. + + // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJiEE12promise_typeD1Ev( + // CHECK: %[[Mem:.+]] = call i8* @llvm.coro.free( + // CHECK: call void @_ZdlPv(i8* %[[Mem]]) + + // Initialize retval from Gro and destroy Gro + + // CHECK: %[[Conv:.+]] = call i32 @_ZN7GroTypecviEv( + // CHECK: store i32 %[[Conv]], i32* %[[RetVal]] + // CHECK: %[[IsActive:.+]] = load i1, i1* %[[GroActive]] + // CHECK: br i1 %[[IsActive]], label %[[CleanupGro:.+]], label %[[Done:.+]] + + // CHECK: [[CleanupGro]]: + // CHECK: call void @_ZN7GroTypeD1Ev( + // CHECK: br label %[[Done]] + + // CHECK: [[Done]]: + // CHECK: %[[LoadRet:.+]] = load i32, i32* %[[RetVal]] + // CHECK: ret i32 %[[LoadRet]] +} Index: lib/CodeGen/CGCoroutine.cpp === --- lib/CodeGen/CGCoroutine.cpp +++ lib/CodeGen/CGCoroutine.cpp @@ -11,6 +11,7 @@ // //===--===// +#include "CGCleanup.h" #include "CodeGenFunction.h" #include "llvm/ADT/ScopeExit.h" #include "clang/AST/StmtCXX.h" @@ -233,6 +234,65 @@ }; } +namespace { +struct GetReturnObjectManager { + CodeGenFunction &CGF; + CGBuilderTy &Builder; + const CoroutineBodyStmt &S; + + Address GroActiveFlag; + CodeGenFunction::AutoVarEmission GroEmission; + + GetReturnObjectManager(CodeGenFunction &CGF, const CoroutineBodyStmt &S) + : CGF(CGF), Builder(CGF.Builder), S(S), GroActiveFlag(Address::invalid()), +GroEmission(CodeGenFunction::AutoVarEmission::invalid()) {} + + // The gro variable has to outlive coroutine frame and coroutine promise, but, + // it can only be initialized after coroutine promise was created, thus, we + // split its emission in two parts. EmitGroAlloca emits an alloca and sets up + // cleanups. Later when coroutine promise is available we initialize the gro + // and sets the flag that the cleanup is now active. + + void EmitGroAlloca() { +auto *GroDeclStmt = dyn_cast(S.getResultDecl()); +if (!GroDeclStmt) { +
[PATCH] D31168: Set FMF for -ffp-contract=fast
rjmccall accepted this revision. rjmccall added a comment. This revision is now accepted and ready to land. Yes, thank you, that's great. https://reviews.llvm.org/D31168 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31669: Fix lambda to block conversion in C++17 by avoiding copy elision for the lambda capture used by the created block
rjmccall added inline comments. Comment at: include/clang/Sema/Initialization.h:124 +/// is a lambda that's captured by a block it's converted to. +bool IsLambdaToBlockConversionEntity; }; It seems less invasive to just give this a new EntityKind. Repository: rL LLVM https://reviews.llvm.org/D31669 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31597: [ObjC++] Conversions from specialized to non-specialized objective-c object type should be preferred over conversions to other object pointers
ahatanak accepted this revision. ahatanak added a comment. This revision is now accepted and ready to land. LGTM Repository: rL LLVM https://reviews.llvm.org/D31597 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r299445 - Preserve vec3 type.
Author: jaykang10 Date: Tue Apr 4 11:40:25 2017 New Revision: 299445 URL: http://llvm.org/viewvc/llvm-project?rev=299445&view=rev Log: Preserve vec3 type. Summary: Preserve vec3 type with CodeGen option. Reviewers: Anastasia, bruno Reviewed By: Anastasia Subscribers: bruno, ahatanak, cfe-commits Differential Revision: https://reviews.llvm.org/D30810 Added: cfe/trunk/test/CodeGenOpenCL/preserve_vec3.cl Modified: cfe/trunk/include/clang/Driver/CC1Options.td cfe/trunk/include/clang/Frontend/CodeGenOptions.def cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CGExprScalar.cpp cfe/trunk/lib/Frontend/CompilerInvocation.cpp Modified: cfe/trunk/include/clang/Driver/CC1Options.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=299445&r1=299444&r2=299445&view=diff == --- cfe/trunk/include/clang/Driver/CC1Options.td (original) +++ cfe/trunk/include/clang/Driver/CC1Options.td Tue Apr 4 11:40:25 2017 @@ -658,6 +658,8 @@ def fdefault_calling_conv_EQ : Joined<[" HelpText<"Set default MS calling convention">; def finclude_default_header : Flag<["-"], "finclude-default-header">, HelpText<"Include the default header file for OpenCL">; +def fpreserve_vec3_type : Flag<["-"], "fpreserve-vec3-type">, + HelpText<"Preserve 3-component vector type">; // FIXME: Remove these entirely once functionality/tests have been excised. def fobjc_gc_only : Flag<["-"], "fobjc-gc-only">, Group, Modified: cfe/trunk/include/clang/Frontend/CodeGenOptions.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.def?rev=299445&r1=299444&r2=299445&view=diff == --- cfe/trunk/include/clang/Frontend/CodeGenOptions.def (original) +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.def Tue Apr 4 11:40:25 2017 @@ -263,6 +263,9 @@ CODEGENOPT(StrictReturn, 1, 1) /// Whether emit extra debug info for sample pgo profile collection. CODEGENOPT(DebugInfoForProfiling, 1, 0) +/// Whether 3-component vector type is preserved. +CODEGENOPT(PreserveVec3Type, 1, 0) + #undef CODEGENOPT #undef ENUM_CODEGENOPT #undef VALUE_CODEGENOPT Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=299445&r1=299444&r2=299445&view=diff == --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Apr 4 11:40:25 2017 @@ -1369,26 +1369,28 @@ llvm::Value *CodeGenFunction::EmitLoadOf QualType TBAABaseType, uint64_t TBAAOffset, bool isNontemporal) { - // For better performance, handle vector loads differently. - if (Ty->isVectorType()) { -const llvm::Type *EltTy = Addr.getElementType(); - -const auto *VTy = cast(EltTy); - -// Handle vectors of size 3 like size 4 for better performance. -if (VTy->getNumElements() == 3) { - - // Bitcast to vec4 type. - llvm::VectorType *vec4Ty = llvm::VectorType::get(VTy->getElementType(), - 4); - Address Cast = Builder.CreateElementBitCast(Addr, vec4Ty, "castToVec4"); - // Now load value. - llvm::Value *V = Builder.CreateLoad(Cast, Volatile, "loadVec4"); - - // Shuffle vector to get vec3. - V = Builder.CreateShuffleVector(V, llvm::UndefValue::get(vec4Ty), - {0, 1, 2}, "extractVec"); - return EmitFromMemory(V, Ty); + if (!CGM.getCodeGenOpts().PreserveVec3Type) { +// For better performance, handle vector loads differently. +if (Ty->isVectorType()) { + const llvm::Type *EltTy = Addr.getElementType(); + + const auto *VTy = cast(EltTy); + + // Handle vectors of size 3 like size 4 for better performance. + if (VTy->getNumElements() == 3) { + +// Bitcast to vec4 type. +llvm::VectorType *vec4Ty = +llvm::VectorType::get(VTy->getElementType(), 4); +Address Cast = Builder.CreateElementBitCast(Addr, vec4Ty, "castToVec4"); +// Now load value. +llvm::Value *V = Builder.CreateLoad(Cast, Volatile, "loadVec4"); + +// Shuffle vector to get vec3. +V = Builder.CreateShuffleVector(V, llvm::UndefValue::get(vec4Ty), +{0, 1, 2}, "extractVec"); +return EmitFromMemory(V, Ty); + } } } @@ -1456,24 +1458,25 @@ void CodeGenFunction::EmitStoreOfScalar( uint64_t TBAAOffset, bool isNontemporal) { - // Handle vectors differently to get better performance. - if (Ty->isVectorType()) { -llvm::Type *
[PATCH] D30810: Preserve vec3 type.
This revision was automatically updated to reflect the committed changes. Closed by commit rL299445: Preserve vec3 type. (authored by jaykang10). Changed prior to commit: https://reviews.llvm.org/D30810?vs=92829&id=94088#toc Repository: rL LLVM https://reviews.llvm.org/D30810 Files: cfe/trunk/include/clang/Driver/CC1Options.td cfe/trunk/include/clang/Frontend/CodeGenOptions.def cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CGExprScalar.cpp cfe/trunk/lib/Frontend/CompilerInvocation.cpp cfe/trunk/test/CodeGenOpenCL/preserve_vec3.cl Index: cfe/trunk/include/clang/Frontend/CodeGenOptions.def === --- cfe/trunk/include/clang/Frontend/CodeGenOptions.def +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.def @@ -263,6 +263,9 @@ /// Whether emit extra debug info for sample pgo profile collection. CODEGENOPT(DebugInfoForProfiling, 1, 0) +/// Whether 3-component vector type is preserved. +CODEGENOPT(PreserveVec3Type, 1, 0) + #undef CODEGENOPT #undef ENUM_CODEGENOPT #undef VALUE_CODEGENOPT Index: cfe/trunk/include/clang/Driver/CC1Options.td === --- cfe/trunk/include/clang/Driver/CC1Options.td +++ cfe/trunk/include/clang/Driver/CC1Options.td @@ -658,6 +658,8 @@ HelpText<"Set default MS calling convention">; def finclude_default_header : Flag<["-"], "finclude-default-header">, HelpText<"Include the default header file for OpenCL">; +def fpreserve_vec3_type : Flag<["-"], "fpreserve-vec3-type">, + HelpText<"Preserve 3-component vector type">; // FIXME: Remove these entirely once functionality/tests have been excised. def fobjc_gc_only : Flag<["-"], "fobjc-gc-only">, Group, Index: cfe/trunk/test/CodeGenOpenCL/preserve_vec3.cl === --- cfe/trunk/test/CodeGenOpenCL/preserve_vec3.cl +++ cfe/trunk/test/CodeGenOpenCL/preserve_vec3.cl @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -triple spir-unknown-unknown -fpreserve-vec3-type | FileCheck %s + +typedef float float3 __attribute__((ext_vector_type(3))); +typedef float float4 __attribute__((ext_vector_type(4))); + +void kernel foo(global float3 *a, global float3 *b) { + // CHECK: %[[LOAD_A:.*]] = load <3 x float>, <3 x float> addrspace(1)* %a + // CHECK: store <3 x float> %[[LOAD_A]], <3 x float> addrspace(1)* %b + *b = *a; +} + +void kernel float4_to_float3(global float3 *a, global float4 *b) { + // CHECK: %[[LOAD_A:.*]] = load <4 x float>, <4 x float> addrspace(1)* %b, align 16 + // CHECK: %[[ASTYPE:.*]] = shufflevector <4 x float> %[[LOAD_A]], <4 x float> undef, <3 x i32> + // CHECK: store <3 x float> %[[ASTYPE:.*]], <3 x float> addrspace(1)* %a, align 16 + *a = __builtin_astype(*b, float3); +} + +void kernel float3_to_float4(global float3 *a, global float4 *b) { + // CHECK: %[[LOAD_A:.*]] = load <3 x float>, <3 x float> addrspace(1)* %a, align 16 + // CHECK: %[[ASTYPE:.*]] = shufflevector <3 x float> %[[LOAD_A]], <3 x float> undef, <4 x i32> + // CHECK: store <4 x float> %[[ASTYPE:.*]], <4 x float> addrspace(1)* %b, align 16 + *b = __builtin_astype(*a, float4); +} Index: cfe/trunk/lib/Frontend/CompilerInvocation.cpp === --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp @@ -729,6 +729,7 @@ } } + Opts.PreserveVec3Type = Args.hasArg(OPT_fpreserve_vec3_type); Opts.InstrumentFunctions = Args.hasArg(OPT_finstrument_functions); Opts.XRayInstrumentFunctions = Args.hasArg(OPT_fxray_instrument); Opts.XRayInstructionThreshold = Index: cfe/trunk/lib/CodeGen/CGExprScalar.cpp === --- cfe/trunk/lib/CodeGen/CGExprScalar.cpp +++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp @@ -3593,19 +3593,26 @@ // vector to get a vec4, then a bitcast if the target type is different. if (NumElementsSrc == 3 && NumElementsDst != 3) { Src = ConvertVec3AndVec4(Builder, CGF, Src, 4); -Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src, - DstTy); + +if (!CGF.CGM.getCodeGenOpts().PreserveVec3Type) { + Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src, + DstTy); +} + Src->setName("astype"); return Src; } // Going from non-vec3 to vec3 is a special case and requires a bitcast // to vec4 if the original type is not vec4, then a shuffle vector to // get a vec3. if (NumElementsSrc != 3 && NumElementsDst == 3) { -auto Vec4Ty = llvm::VectorType::get(DstTy->getVectorElementType(), 4); -Src = createCastsForTypeOfSameSize(Builder, CGF.CGM.getDataLayout(), Src, - Vec4Ty); +if (!CGF.CGM.getCodeGenOpts().PreserveVec3Type) { + auto Vec4Ty = llvm::Vect
[PATCH] D30810: Preserve vec3 type.
jaykang10 added a comment. In https://reviews.llvm.org/D30810#718176, @Anastasia wrote: > LGTM! Thanks! Thanks Anastasia! Merge Done! Repository: rL LLVM https://reviews.llvm.org/D30810 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31667: [Sema] Extend GetSignedVectorType to deal with non ExtVector types
bruno added a comment. Great! Thanks for improving this. Comment at: include/clang/Sema/Sema.h:9287 bool AllowBothBool, bool AllowBoolConversion); - QualType GetSignedVectorType(QualType V); + QualType GetSignedVectorType(QualType V, bool WantExtVectorType); QualType CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS, Can you change `WantExtVector` to `UseExtVector`? Comment at: lib/Sema/SemaExpr.cpp:9719 +// gets picked over long long. +QualType Sema::GetSignedVectorType(QualType V, bool WantExtVector) { const VectorType *VTy = V->getAs(); Do we really need to pass `WantExtVector` here? Why relying on `V` being ext_vector or generic isn't enough to define `WantExtVector`? Comment at: lib/Sema/SemaExpr.cpp:9803 // Return a signed type for the vector. - return GetSignedVectorType(vType); + return GetSignedVectorType(vType, isExtVectorType); } So in `getLangOpts().OpenCL` mode we want to get a ext_vec even if `vType` isn't ext_vec? Would that ever happen? Comment at: lib/Sema/SemaExpr.cpp:9821 + + return GetSignedVectorType(LHS.get()->getType(), isExtVectorType); } Same question applies here Comment at: lib/Sema/SemaExpr.cpp:11760 // Vector logical not returns the signed variant of the operand type. - resultType = GetSignedVectorType(resultType); + resultType = GetSignedVectorType(resultType, true); break; Use the idiom `...(resultType, true/*WantExtVector*/);` Comment at: test/Sema/vector-ops.c:16 // Comparison operators - v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from 'int __attribute__((ext_vector_type(2)))' (vector of 2 'int' values)}} + v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int int' (vector of 2 'int' values)}} v2sa = (v2ua==v2sa); Can you also add a test for the `CheckVectorLogicalOperands` case? https://reviews.llvm.org/D31667 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31591: Fix a bug which access nullptr and cause segmentation fault
yamaguchi updated this revision to Diff 94090. yamaguchi added a comment. Add relative path to the file. https://reviews.llvm.org/D31591 Files: clang/test/Sema/sema-segvcheck.c lib/Sema/SemaInit.cpp Index: clang/test/Sema/sema-segvcheck.c === --- clang/test/Sema/sema-segvcheck.c +++ clang/test/Sema/sema-segvcheck.c @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only %s; test $? -eq 1 + +typedef struct { + union { +unsigned long long house; +struct { + unsigned cat1; + unsigned cat2; +}; + }; +} struct_0; + + +typedef struct { + union { +struct { + union { +unsigned cows; +struct { + unsigned char c:1; +}; + }; +}; + }; + + union { +struct { + unsigned bird0; + unsigned bird1; +}; + }; +} struct_1; + + +typedef struct { + struct_0 s0; + struct_1 s1[1]; +} struct_2; + +struct_2 s = { + .s0 = { +.dog = 0x, // expected-error{{field designator}} + }, + + .s1[0] = { +.cows = 0x5050, +.c = 1, + }, +}; Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -2269,15 +2269,17 @@ assert(StructuredList->getNumInits() == 1 && "A union should never have more than one initializer!"); - // We're about to throw away an initializer, emit warning. - SemaRef.Diag(D->getFieldLoc(), - diag::warn_initializer_overrides) -<< D->getSourceRange(); Expr *ExistingInit = StructuredList->getInit(0); - SemaRef.Diag(ExistingInit->getLocStart(), - diag::note_previous_initializer) -<< /*FIXME:has side effects=*/0 -<< ExistingInit->getSourceRange(); + if (ExistingInit) { +// We're about to throw away an initializer, emit warning. +SemaRef.Diag(D->getFieldLoc(), + diag::warn_initializer_overrides) + << D->getSourceRange(); +SemaRef.Diag(ExistingInit->getLocStart(), + diag::note_previous_initializer) + << /*FIXME:has side effects=*/0 + << ExistingInit->getSourceRange(); + } // remove existing initializer StructuredList->resizeInits(SemaRef.Context, 0); Index: clang/test/Sema/sema-segvcheck.c === --- clang/test/Sema/sema-segvcheck.c +++ clang/test/Sema/sema-segvcheck.c @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only %s; test $? -eq 1 + +typedef struct { + union { +unsigned long long house; +struct { + unsigned cat1; + unsigned cat2; +}; + }; +} struct_0; + + +typedef struct { + union { +struct { + union { +unsigned cows; +struct { + unsigned char c:1; +}; + }; +}; + }; + + union { +struct { + unsigned bird0; + unsigned bird1; +}; + }; +} struct_1; + + +typedef struct { + struct_0 s0; + struct_1 s1[1]; +} struct_2; + +struct_2 s = { + .s0 = { +.dog = 0x, // expected-error{{field designator}} + }, + + .s1[0] = { +.cows = 0x5050, +.c = 1, + }, +}; Index: lib/Sema/SemaInit.cpp === --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -2269,15 +2269,17 @@ assert(StructuredList->getNumInits() == 1 && "A union should never have more than one initializer!"); - // We're about to throw away an initializer, emit warning. - SemaRef.Diag(D->getFieldLoc(), - diag::warn_initializer_overrides) -<< D->getSourceRange(); Expr *ExistingInit = StructuredList->getInit(0); - SemaRef.Diag(ExistingInit->getLocStart(), - diag::note_previous_initializer) -<< /*FIXME:has side effects=*/0 -<< ExistingInit->getSourceRange(); + if (ExistingInit) { +// We're about to throw away an initializer, emit warning. +SemaRef.Diag(D->getFieldLoc(), + diag::warn_initializer_overrides) + << D->getSourceRange(); +SemaRef.Diag(ExistingInit->getLocStart(), + diag::note_previous_initializer) + << /*FIXME:has side effects=*/0 + << ExistingInit->getSourceRange(); + } // remove existing initializer StructuredList->resizeInits(SemaRef.Context, 0); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r299447 - [Bug 25404] Fix crash on typedef in OpenCL 2.0
Author: stulova Date: Tue Apr 4 11:50:46 2017 New Revision: 299447 URL: http://llvm.org/viewvc/llvm-project?rev=299447&view=rev Log: [Bug 25404] Fix crash on typedef in OpenCL 2.0 Fixed the assertion due to absence of source location for implicitly defined types (using addImplicitTypedef()). During Sema checks the source location is being expected and therefore an assertion is triggered. The change is not specific to OpenCL. But it is particularly common for OpenCL types to be declared implicitly in Clang to support the mode without the standard header. Differential Revision: https://reviews.llvm.org/D31397 Added: cfe/trunk/test/SemaOpenCL/types.cl Modified: cfe/trunk/lib/Sema/SemaDecl.cpp Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=299447&r1=299446&r2=299447&view=diff == --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Apr 4 11:50:46 2017 @@ -2154,7 +2154,9 @@ void Sema::MergeTypedefNameDecl(Scope *S // -Wtypedef-redefinition. If either the original or the redefinition is // in a system header, don't emit this for compatibility with GCC. if (getDiagnostics().getSuppressSystemWarnings() && - (Context.getSourceManager().isInSystemHeader(Old->getLocation()) || + // Some standard types are defined implicitly in Clang (e.g. OpenCL). + (Old->isImplicit() || + Context.getSourceManager().isInSystemHeader(Old->getLocation()) || Context.getSourceManager().isInSystemHeader(New->getLocation( return; Added: cfe/trunk/test/SemaOpenCL/types.cl URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/types.cl?rev=299447&view=auto == --- cfe/trunk/test/SemaOpenCL/types.cl (added) +++ cfe/trunk/test/SemaOpenCL/types.cl Tue Apr 4 11:50:46 2017 @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -fsyntax-only + +// expected-no-diagnostics + +// Check redefinition of standard types +typedef atomic_int atomic_flag; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31397: [Bug 25404] Fix crash on typedef in OpenCL 2.0
This revision was automatically updated to reflect the committed changes. Closed by commit rL299447: [Bug 25404] Fix crash on typedef in OpenCL 2.0 (authored by stulova). Changed prior to commit: https://reviews.llvm.org/D31397?vs=93226&id=94091#toc Repository: rL LLVM https://reviews.llvm.org/D31397 Files: cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/SemaOpenCL/types.cl Index: cfe/trunk/lib/Sema/SemaDecl.cpp === --- cfe/trunk/lib/Sema/SemaDecl.cpp +++ cfe/trunk/lib/Sema/SemaDecl.cpp @@ -2154,7 +2154,9 @@ // -Wtypedef-redefinition. If either the original or the redefinition is // in a system header, don't emit this for compatibility with GCC. if (getDiagnostics().getSuppressSystemWarnings() && - (Context.getSourceManager().isInSystemHeader(Old->getLocation()) || + // Some standard types are defined implicitly in Clang (e.g. OpenCL). + (Old->isImplicit() || + Context.getSourceManager().isInSystemHeader(Old->getLocation()) || Context.getSourceManager().isInSystemHeader(New->getLocation( return; Index: cfe/trunk/test/SemaOpenCL/types.cl === --- cfe/trunk/test/SemaOpenCL/types.cl +++ cfe/trunk/test/SemaOpenCL/types.cl @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -fsyntax-only + +// expected-no-diagnostics + +// Check redefinition of standard types +typedef atomic_int atomic_flag; Index: cfe/trunk/lib/Sema/SemaDecl.cpp === --- cfe/trunk/lib/Sema/SemaDecl.cpp +++ cfe/trunk/lib/Sema/SemaDecl.cpp @@ -2154,7 +2154,9 @@ // -Wtypedef-redefinition. If either the original or the redefinition is // in a system header, don't emit this for compatibility with GCC. if (getDiagnostics().getSuppressSystemWarnings() && - (Context.getSourceManager().isInSystemHeader(Old->getLocation()) || + // Some standard types are defined implicitly in Clang (e.g. OpenCL). + (Old->isImplicit() || + Context.getSourceManager().isInSystemHeader(Old->getLocation()) || Context.getSourceManager().isInSystemHeader(New->getLocation( return; Index: cfe/trunk/test/SemaOpenCL/types.cl === --- cfe/trunk/test/SemaOpenCL/types.cl +++ cfe/trunk/test/SemaOpenCL/types.cl @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -cl-std=CL2.0 -verify -fsyntax-only + +// expected-no-diagnostics + +// Check redefinition of standard types +typedef atomic_int atomic_flag; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D25866: [Sema] Support implicit scalar to vector conversions
bruno added inline comments. Comment at: lib/Sema/SemaExpr.cpp:8032 + + return InvalidOperands(Loc, LHS, RHS); +} Double checking here: are there tests for the `InvalidOperands` case above? Comment at: lib/Sema/SemaExpr.cpp:8163 +/// type without causing truncation of Scalar. +static bool tryGCCVectorConvertAndSpalt(Sema &S, ExprResult *Scalar, +ExprResult *Vector) { `Spalt` -> `Splat` Comment at: lib/Sema/SemaExpr.cpp:8188 + //type and then perform the rest of the checks here. GCC as of + //pre-release 7.0 does not accept this though. + if (VectorEltTy->isIntegralType(S.Context) && Is this something that GCC is going to support at some point? Regardless of GCC, do we want this behavior? Comment at: lib/Sema/SemaExpr.cpp:10019 isa(vType->getAs()) || getLangOpts().OpenCL; + if ((!getLangOpts().CPlusPlus && !getLangOpts().OpenCL) && !isExtVectorType) +return InvalidVectorOperands(Loc, LHS, RHS); Why `!getLangOpts().CPlusPlus` is a requirement here? Comment at: test/Sema/vector-g++-compat.cpp:1 +// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything -std=c++11 + Can you rename this file to `vector-gcc-compat.cpp` instead? Comment at: test/Sema/vector-g++-compat.cpp:155 + unsigned long long d) { // expected-warning {{'long long' is incompatible with C++98}} + + v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f}; Remove all these extra new lines after the function signature here, in the functions below and in the other added test file for c++. https://reviews.llvm.org/D25866 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31673: Allow casting C pointers declared using extern "C" to ObjC pointer types
ahatanak created this revision. ARCCastChecker::VisitDeclRefExpr allows casting a constant pointer declared in a header file to an ObjC pointer type. However, it rejects a cast from a variable declared with a language linkage specification (e.g., extern "C") to an ObjC pointer type. According to the standard, declarations directly contained in a language linkage specification (single line "extern C") are treated as if they contain the extern specifier for the purpose of determining whether they are definitions, so such variables should be treated as declarations unless they have initializers. This patch replaces the call to VarDecl::getStorageClass (which returns SC_None for extern "C" variables) with a call to VarDecl::isThisDeclarationADefinition to detect variable declarations more precisely. rdar://problem/29249853 https://reviews.llvm.org/D31673 Files: lib/Sema/SemaExprObjC.cpp test/SemaObjCXX/arc-bridged-cast.mm Index: test/SemaObjCXX/arc-bridged-cast.mm === --- test/SemaObjCXX/arc-bridged-cast.mm +++ test/SemaObjCXX/arc-bridged-cast.mm @@ -52,3 +52,16 @@ ref = (__bridge_retained CFAnnotatedObjectRef) CreateSomething(); ref = (__bridge_retained CFAnnotatedObjectRef) CreateNSString(); } + +extern const CFAnnotatedObjectRef r0; +extern const CFAnnotatedObjectRef r1 = 0; +extern "C" const CFAnnotatedObjectRef r2; +extern "C" const CFAnnotatedObjectRef r3 = 0; + +void testExternC() { + id obj; + obj = (id)r0; + obj = (id)r1; // expected-error{{cast of C pointer type 'CFAnnotatedObjectRef' (aka 'const __CFAnnotatedObject *') to Objective-C pointer type 'id' requires a bridged cast}} expected-note{{use __bridge to convert directly}} expected-note{{use __bridge_transfer to transfer ownership of a +1 'CFAnnotatedObjectRef'}} + obj = (id)r2; + obj = (id)r3; // expected-error{{cast of C pointer type 'CFAnnotatedObjectRef' (aka 'const __CFAnnotatedObject *') to Objective-C pointer type 'id' requires a bridged cast}} expected-note{{use __bridge to convert directly}} expected-note{{use __bridge_transfer to transfer ownership of a +1 'CFAnnotatedObjectRef'}} +} Index: lib/Sema/SemaExprObjC.cpp === --- lib/Sema/SemaExprObjC.cpp +++ lib/Sema/SemaExprObjC.cpp @@ -3355,7 +3355,7 @@ if (isAnyRetainable(TargetClass) && isAnyRetainable(SourceClass) && var && - var->getStorageClass() == SC_Extern && + !var->isThisDeclarationADefinition() && var->getType().isConstQualified()) { // In system headers, they can also be assumed to be immune to retains. Index: test/SemaObjCXX/arc-bridged-cast.mm === --- test/SemaObjCXX/arc-bridged-cast.mm +++ test/SemaObjCXX/arc-bridged-cast.mm @@ -52,3 +52,16 @@ ref = (__bridge_retained CFAnnotatedObjectRef) CreateSomething(); ref = (__bridge_retained CFAnnotatedObjectRef) CreateNSString(); } + +extern const CFAnnotatedObjectRef r0; +extern const CFAnnotatedObjectRef r1 = 0; +extern "C" const CFAnnotatedObjectRef r2; +extern "C" const CFAnnotatedObjectRef r3 = 0; + +void testExternC() { + id obj; + obj = (id)r0; + obj = (id)r1; // expected-error{{cast of C pointer type 'CFAnnotatedObjectRef' (aka 'const __CFAnnotatedObject *') to Objective-C pointer type 'id' requires a bridged cast}} expected-note{{use __bridge to convert directly}} expected-note{{use __bridge_transfer to transfer ownership of a +1 'CFAnnotatedObjectRef'}} + obj = (id)r2; + obj = (id)r3; // expected-error{{cast of C pointer type 'CFAnnotatedObjectRef' (aka 'const __CFAnnotatedObject *') to Objective-C pointer type 'id' requires a bridged cast}} expected-note{{use __bridge to convert directly}} expected-note{{use __bridge_transfer to transfer ownership of a +1 'CFAnnotatedObjectRef'}} +} Index: lib/Sema/SemaExprObjC.cpp === --- lib/Sema/SemaExprObjC.cpp +++ lib/Sema/SemaExprObjC.cpp @@ -3355,7 +3355,7 @@ if (isAnyRetainable(TargetClass) && isAnyRetainable(SourceClass) && var && - var->getStorageClass() == SC_Extern && + !var->isThisDeclarationADefinition() && var->getType().isConstQualified()) { // In system headers, they can also be assumed to be immune to retains. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31591: Fix a bug which access nullptr and cause segmentation fault
ahatanak added inline comments. Comment at: clang/test/Sema/sema-segvcheck.c:3 +// RUN: %clang_cc1 -fsyntax-only %s; test $? -eq 1 + +typedef struct { You can simplify the test case. Compiling the following code still segfaults: ``` typedef struct { unsigned long long house; } struct_0; typedef union { unsigned cows; unsigned char c; } union_1; typedef struct { struct_0 s0; union_1 s1; } struct_2; struct_2 s = { .s0 = { .dog = 0x0009, }, .s1 = { .cows = 0x0055, .c = 1, }, }; ``` Also, would it be better to add this test to an existing file (e.g., test/Sema/designated-initializers.c) rather than creating a new file? https://reviews.llvm.org/D31591 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31404: [OpenCL] Allow alloca return non-zero private pointer
Anastasia added inline comments. Comment at: include/clang/AST/ASTContext.h:2328 +return AddrSpaceMapMangling || + AS >= LangAS::target_first; } yaxunl wrote: > Anastasia wrote: > > So we couldn't use the LangAS::Count instead? > > > > I have the same comment in other places that use LangAS::target_first. Why > > couldn't we simply use LangAS::Count? It there any point in having two tags? > > > > Another comment is why do we need ASes specified by > > `__attribute__((address_space(n)))` to be unique enum number at the end of > > named ASes of OpenCL and CUDA? I think conceptually the full range of ASes > > can be used in C because the ASes from OpenCL and CUDA are not available > > there anyways. > I will use LangAS::Count instead and remove target_first, since their values > are the same. > > For your second question: the values for `__attribute__((address_space(n)))` > need to be different from the language specific address space values because > they are mapped to target address space differently. > > For language specific address space, they are mapped through a target defined > mapping table. > > For `__attribute__((address_space(n)))`, the target address space should be > the same as n, without going through the mapping table. > > If they are defined in overlapping value ranges, they cannot be handled in > different ways. > > Target address space map currently corresponds to the named address spaces of OpenCL and CUDA only. So if the idea is to avoid overlapping with those we should extend the table? Although, I don't see how this can be done because it will require fixed semantic of address spaces in C which is currently undefined. Comment at: include/clang/AST/Type.h:345 + return Addr - LangAS::Count; +// ToDo: The diagnostic messages where Addr may be 0 should be fixed +// since it cannot differentiate the situation where 0 denotes the default ToDo -> TODO Comment at: lib/AST/ASTContext.cpp:9556 + if (AS == LangAS::Default && LangOpts.OpenCL) +return getTargetInfo().getDataLayout().getAllocaAddrSpace(); + if (AS >= LangAS::target_first) yaxunl wrote: > Anastasia wrote: > > t-tye wrote: > > > An alternative to doing this would be to add an opencl_private to LangAS > > > and have each target map it accordingly. Then this could be: > > > > > > ``` > > > // If a target specific address space was specified, simply return it. > > > if (AS >= LangAS::target_first) > > > return AS - LangAS::target_first; > > > // For OpenCL, only function local variables are not explicitly marked > > > with > > > // an address space in the AST, so treat them as the OpenCL private > > > address space. > > > if (!AS && LangOpts.OpenCL) > > > AS = LangAS::opencl_private; > > > return (*AddrSpaceMap)[AS]; > > > ``` > > > This seems to better express what is happening here. If no address space > > > was specified, and the language is OpenCL, then treat it as OpenCL > > > private and map it according to the target mapping. > > > > > > If wanted to eliminate the LangAS::Default named constant then that would > > > be possible as it is no longer being used by name. However, would need to > > > ensure that the first named enumerators starts at 1 so that 0 is left as > > > the "no value explicitly specified" value that each target must map to > > > the target specific generic address space. > > I would very much like to see `opencl_private` represented explicitly. This > > would allow us to simplify some parsing and also enable proper support of > > `NULL ` literal (that has no AS by the spec). > > > > We can of course do this refactoring work as a separate step. > Introducing opencl_private could incur quite a few changes to AST, Sema, and > lit tests. > > We'd better do that in another patch since the main objective of this patch > is to get Clang codegen work with the new alloca API and non-zero private > address space. > Makes sense! Comment at: lib/Sema/SemaExprCXX.cpp:3121 -if (unsigned AddressSpace = Pointee.getAddressSpace()) +if (Pointee.getQualifiers().getAddressSpace()) return Diag(Ex.get()->getLocStart(), `Pointee.getAddressSpace()` wouldn't work any more? https://reviews.llvm.org/D31404 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31591: Fix a bug which access nullptr and cause segmentation fault
ruiu added a comment. Is this a minimal test case that can produce the issue? It'd be awesome if you can reduce it. sema-segvcheck.c is not a good name for this test because that name can be used for any crash bug. You want to see other files in the same directory to name your file so that it's consistent with other files. If you don't come up with a name, I'd name it pr32280.c. https://reviews.llvm.org/D31591 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31404: [OpenCL] Allow alloca return non-zero private pointer
Anastasia added inline comments. Comment at: include/clang/AST/ASTContext.h:2328 +return AddrSpaceMapMangling || + AS >= LangAS::target_first; } Anastasia wrote: > yaxunl wrote: > > Anastasia wrote: > > > So we couldn't use the LangAS::Count instead? > > > > > > I have the same comment in other places that use LangAS::target_first. > > > Why couldn't we simply use LangAS::Count? It there any point in having > > > two tags? > > > > > > Another comment is why do we need ASes specified by > > > `__attribute__((address_space(n)))` to be unique enum number at the end > > > of named ASes of OpenCL and CUDA? I think conceptually the full range of > > > ASes can be used in C because the ASes from OpenCL and CUDA are not > > > available there anyways. > > I will use LangAS::Count instead and remove target_first, since their > > values are the same. > > > > For your second question: the values for > > `__attribute__((address_space(n)))` need to be different from the language > > specific address space values because they are mapped to target address > > space differently. > > > > For language specific address space, they are mapped through a target > > defined mapping table. > > > > For `__attribute__((address_space(n)))`, the target address space should be > > the same as n, without going through the mapping table. > > > > If they are defined in overlapping value ranges, they cannot be handled in > > different ways. > > > > > Target address space map currently corresponds to the named address spaces of > OpenCL and CUDA only. So if the idea is to avoid overlapping with those we > should extend the table? Although, I don't see how this can be done because > it will require fixed semantic of address spaces in C which is currently > undefined. Perhaps I am missing something but I don't see any change here that makes non-named address spaces follow different path for the target. Also does this change relate to alloca extension in some way? I still struggle to understand this fully... All I can see is that this change restricts overlapping of named and non-named address spaces but I can't clearly understand the motivation for this. Comment at: lib/Basic/Targets.cpp:2035 static const LangAS::Map AMDGPUPrivateIsZeroMap = { +4, // Default 1, // opencl_global This should use address space attribute 4 for all non-AS type objects. Could we make sure we have a codegen test for this? https://reviews.llvm.org/D31404 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27418: [X86][inline-asm] Add support for MS 'EVEN' directive
This revision was automatically updated to reflect the committed changes. Closed by commit rL299454: [X86][inline-asm] Add support for MS 'EVEN' directive (authored by coby). Changed prior to commit: https://reviews.llvm.org/D27418?vs=80280&id=94095#toc Repository: rL LLVM https://reviews.llvm.org/D27418 Files: cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c Index: cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c === --- cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c +++ cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fasm-blocks -emit-llvm -o - | FileCheck %s + +// CHECK: .byte 64 +// CHECK: .byte 64 +// CHECK: .byte 64 +// CHECK: .even +void t1() { + __asm { +.byte 64 +.byte 64 +.byte 64 +EVEN +mov eax, ebx + } +} Index: cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c === --- cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c +++ cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fasm-blocks -emit-llvm -o - | FileCheck %s + +// CHECK: .byte 64 +// CHECK: .byte 64 +// CHECK: .byte 64 +// CHECK: .even +void t1() { + __asm { +.byte 64 +.byte 64 +.byte 64 +EVEN +mov eax, ebx + } +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r299454 - [X86][inline-asm] Add support for MS 'EVEN' directive
Author: coby Date: Tue Apr 4 12:58:28 2017 New Revision: 299454 URL: http://llvm.org/viewvc/llvm-project?rev=299454&view=rev Log: [X86][inline-asm] Add support for MS 'EVEN' directive MS assembly syntax provide us with the 'EVEN' directive as a synonymous to at&t '.even'. This patch include the (small, simple) changes need to allow it. llvm-side: https://reviews.llvm.org/D27417 Differential Revision: https://reviews.llvm.org/D27418 Added: cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c (with props) Added: cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c?rev=299454&view=auto == --- cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c (added) +++ cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c Tue Apr 4 12:58:28 2017 @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fasm-blocks -emit-llvm -o - | FileCheck %s + +// CHECK: .byte 64 +// CHECK: .byte 64 +// CHECK: .byte 64 +// CHECK: .even +void t1() { + __asm { +.byte 64 +.byte 64 +.byte 64 +EVEN +mov eax, ebx + } +} Propchange: cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c -- svn:eol-style = native Propchange: cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c -- svn:keywords = Author Date Id Rev URL Propchange: cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c -- svn:mime-type = text/plain ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D20449: [Basic] Change x86_64-windows-macho targets to use Windows-style va_lists.
cdavis5x added a comment. Extremely belated ping. https://reviews.llvm.org/D20449 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31404: [OpenCL] Allow alloca return non-zero private pointer
yaxunl marked 8 inline comments as done. yaxunl added inline comments. Comment at: include/clang/AST/ASTContext.h:2328 +return AddrSpaceMapMangling || + AS >= LangAS::target_first; } Anastasia wrote: > Anastasia wrote: > > yaxunl wrote: > > > Anastasia wrote: > > > > So we couldn't use the LangAS::Count instead? > > > > > > > > I have the same comment in other places that use LangAS::target_first. > > > > Why couldn't we simply use LangAS::Count? It there any point in having > > > > two tags? > > > > > > > > Another comment is why do we need ASes specified by > > > > `__attribute__((address_space(n)))` to be unique enum number at the end > > > > of named ASes of OpenCL and CUDA? I think conceptually the full range > > > > of ASes can be used in C because the ASes from OpenCL and CUDA are not > > > > available there anyways. > > > I will use LangAS::Count instead and remove target_first, since their > > > values are the same. > > > > > > For your second question: the values for > > > `__attribute__((address_space(n)))` need to be different from the > > > language specific address space values because they are mapped to target > > > address space differently. > > > > > > For language specific address space, they are mapped through a target > > > defined mapping table. > > > > > > For `__attribute__((address_space(n)))`, the target address space should > > > be the same as n, without going through the mapping table. > > > > > > If they are defined in overlapping value ranges, they cannot be handled > > > in different ways. > > > > > > > > Target address space map currently corresponds to the named address spaces > > of OpenCL and CUDA only. So if the idea is to avoid overlapping with those > > we should extend the table? Although, I don't see how this can be done > > because it will require fixed semantic of address spaces in C which is > > currently undefined. > Perhaps I am missing something but I don't see any change here that makes > non-named address spaces follow different path for the target. > > Also does this change relate to alloca extension in some way? I still > struggle to understand this fully... > > All I can see is that this change restricts overlapping of named and > non-named address spaces but I can't clearly understand the motivation for > this. `__attribute__((address_space(n)))` is used in C and C++ to specify target address space for a variable. For example, https://github.com/llvm-mirror/clang/blob/master/test/Sema/address_spaces.c Many cases they just need to put a variable in certain target address space and do not need specific semantics for these address spaces. Comment at: include/clang/AST/ASTContext.h:2328 +return AddrSpaceMapMangling || + AS >= LangAS::target_first; } yaxunl wrote: > Anastasia wrote: > > Anastasia wrote: > > > yaxunl wrote: > > > > Anastasia wrote: > > > > > So we couldn't use the LangAS::Count instead? > > > > > > > > > > I have the same comment in other places that use > > > > > LangAS::target_first. Why couldn't we simply use LangAS::Count? It > > > > > there any point in having two tags? > > > > > > > > > > Another comment is why do we need ASes specified by > > > > > `__attribute__((address_space(n)))` to be unique enum number at the > > > > > end of named ASes of OpenCL and CUDA? I think conceptually the full > > > > > range of ASes can be used in C because the ASes from OpenCL and CUDA > > > > > are not available there anyways. > > > > I will use LangAS::Count instead and remove target_first, since their > > > > values are the same. > > > > > > > > For your second question: the values for > > > > `__attribute__((address_space(n)))` need to be different from the > > > > language specific address space values because they are mapped to > > > > target address space differently. > > > > > > > > For language specific address space, they are mapped through a target > > > > defined mapping table. > > > > > > > > For `__attribute__((address_space(n)))`, the target address space > > > > should be the same as n, without going through the mapping table. > > > > > > > > If they are defined in overlapping value ranges, they cannot be handled > > > > in different ways. > > > > > > > > > > > Target address space map currently corresponds to the named address > > > spaces of OpenCL and CUDA only. So if the idea is to avoid overlapping > > > with those we should extend the table? Although, I don't see how this can > > > be done because it will require fixed semantic of address spaces in C > > > which is currently undefined. > > Perhaps I am missing something but I don't see any change here that makes > > non-named address spaces follow different path for the target. > > > > Also does this change relate to alloca extension in some way? I still > > struggle to understand this fully... > > > > All
r299459 - [fixup][X86][inline-asm] Add support for MS 'EVEN' directive
Author: coby Date: Tue Apr 4 14:20:21 2017 New Revision: 299459 URL: http://llvm.org/viewvc/llvm-project?rev=299459&view=rev Log: [fixup][X86][inline-asm] Add support for MS 'EVEN' directive refining tested targets resolution, to amend failures caused by rL299454 Modified: cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c Modified: cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c?rev=299459&r1=299458&r2=299459&view=diff == --- cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c (original) +++ cfe/trunk/test/CodeGen/ms-inline-asm-EVEN.c Tue Apr 4 14:20:21 2017 @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 %s -triple i386-unknown-unknown -fasm-blocks -emit-llvm -o - | FileCheck %s +// REQUIRES: x86-registered-target +// RUN: %clang_cc1 %s -triple i386-apple-darwin10 -fasm-blocks -emit-llvm -o - | FileCheck %s // CHECK: .byte 64 // CHECK: .byte 64 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31404: [OpenCL] Allow alloca return non-zero private pointer
yaxunl updated this revision to Diff 94102. yaxunl marked 2 inline comments as done. yaxunl added a comment. Revised by Anastasia's comments. Add lit test for `__attribute__((address_space(0)))` and default address space. https://reviews.llvm.org/D31404 Files: include/clang/AST/ASTContext.h include/clang/AST/Type.h include/clang/Basic/AddressSpaces.h lib/AST/ASTContext.cpp lib/AST/ExprClassification.cpp lib/AST/TypePrinter.cpp lib/Basic/Targets.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/CGExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaType.cpp test/CodeGen/address-space.c test/CodeGen/default-address-space.c test/CodeGenOpenCL/address-space-constant-initializers.cl test/CodeGenOpenCL/address-spaces.cl test/CodeGenOpenCL/amdgpu-env-amdgiz.cl test/CodeGenOpenCL/vla.cl test/Sema/address_spaces.c test/Sema/invalid-assignment-constant-address-space.c test/SemaOpenCL/invalid-assignment-constant-address-space.cl Index: test/SemaOpenCL/invalid-assignment-constant-address-space.cl === --- /dev/null +++ test/SemaOpenCL/invalid-assignment-constant-address-space.cl @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only + +int constant c[3] = {0}; + +void foo() { + c[0] = 1; //expected-error{{read-only variable is not assignable}} +} Index: test/Sema/invalid-assignment-constant-address-space.c === --- test/Sema/invalid-assignment-constant-address-space.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only - -#define OPENCL_CONSTANT 8388354 -int __attribute__((address_space(OPENCL_CONSTANT))) c[3] = {0}; - -void foo() { - c[0] = 1; //expected-error{{read-only variable is not assignable}} -} Index: test/Sema/address_spaces.c === --- test/Sema/address_spaces.c +++ test/Sema/address_spaces.c @@ -20,7 +20,7 @@ _AS1 int arrarr[5][5]; // expected-error {{automatic variable qualified with an address space}} __attribute__((address_space(-1))) int *_boundsA; // expected-error {{address space is negative}} - __attribute__((address_space(0x7F))) int *_boundsB; + __attribute__((address_space(0x7F))) int *_boundsB; // expected-error {{address space is larger than the maximum supported}} __attribute__((address_space(0x100))) int *_boundsC; // expected-error {{address space is larger than the maximum supported}} // chosen specifically to overflow 32 bits and come out reasonable __attribute__((address_space(4294967500))) int *_boundsD; // expected-error {{address space is larger than the maximum supported}} Index: test/CodeGenOpenCL/vla.cl === --- test/CodeGenOpenCL/vla.cl +++ test/CodeGenOpenCL/vla.cl @@ -1,18 +1,26 @@ -// RUN: %clang_cc1 -emit-llvm -triple "spir-unknown-unknown" -O0 -cl-std=CL2.0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -triple "spir-unknown-unknown" -O0 -cl-std=CL2.0 -o - %s | FileCheck -check-prefixes=CHECK,SPIR %s +// RUN: %clang_cc1 -emit-llvm -triple amdgcn-amd-amdhsa-opencl -O0 -cl-std=CL2.0 -o - %s | FileCheck -check-prefixes=CHECK,SPIR %s +// RUN: %clang_cc1 -emit-llvm -triple amdgcn-amd-amdhsa-amdgizcl -O0 -cl-std=CL2.0 -o - %s | FileCheck -check-prefixes=CHECK,GIZ %s constant int sz0 = 5; -// CHECK: @sz0 = addrspace(2) constant i32 5 +// SPIR: @sz0 = addrspace(2) constant i32 5 +// GIZ: @sz0 = addrspace(4) constant i32 5 const global int sz1 = 16; // CHECK: @sz1 = addrspace(1) constant i32 16 const constant int sz2 = 8; -// CHECK: @sz2 = addrspace(2) constant i32 8 +// SPIR: @sz2 = addrspace(2) constant i32 8 +// GIZ: @sz2 = addrspace(4) constant i32 8 // CHECK: @testvla.vla2 = internal addrspace(3) global [8 x i16] undef kernel void testvla() { int vla0[sz0]; -// CHECK: %vla0 = alloca [5 x i32] +// SPIR: %vla0 = alloca [5 x i32] +// SPIR-NOT: %vla0 = alloca [5 x i32]{{.*}}addrspace +// GIZ: %vla0 = alloca [5 x i32]{{.*}}addrspace(5) char vla1[sz1]; -// CHECK: %vla1 = alloca [16 x i8] +// SPIR: %vla1 = alloca [16 x i8] +// SPIR-NOT: %vla1 = alloca [16 x i8]{{.*}}addrspace +// GIZ: %vla1 = alloca [16 x i8]{{.*}}addrspace(5) local short vla2[sz2]; } Index: test/CodeGenOpenCL/amdgpu-env-amdgiz.cl === --- test/CodeGenOpenCL/amdgpu-env-amdgiz.cl +++ test/CodeGenOpenCL/amdgpu-env-amdgiz.cl @@ -4,6 +4,6 @@ // RUN: %clang_cc1 %s -O0 -triple amdgcn---amdgizcl -emit-llvm -o - | FileCheck -check-prefix=GIZ %s // CHECK: target datalayout = "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64" -// GIZ: target datalayout = "e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v
[clang-tools-extra] r299461 - [clangd] Link against clangSema
Author: jdevlieghere Date: Tue Apr 4 14:42:29 2017 New Revision: 299461 URL: http://llvm.org/viewvc/llvm-project?rev=299461&view=rev Log: [clangd] Link against clangSema Fixes linking issue introduced by rL299421 when building LLVM with shared libraries. Modified: clang-tools-extra/trunk/clangd/CMakeLists.txt Modified: clang-tools-extra/trunk/clangd/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CMakeLists.txt?rev=299461&r1=299460&r2=299461&view=diff == --- clang-tools-extra/trunk/clangd/CMakeLists.txt (original) +++ clang-tools-extra/trunk/clangd/CMakeLists.txt Tue Apr 4 14:42:29 2017 @@ -12,6 +12,7 @@ target_link_libraries(clangd clangBasic clangFormat clangFrontend + clangSema clangTooling clangToolingCore LLVMSupport ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r299463 - [analyzer] Add new Z3 constraint manager backend
Author: ddcc Date: Tue Apr 4 14:52:25 2017 New Revision: 299463 URL: http://llvm.org/viewvc/llvm-project?rev=299463&view=rev Log: [analyzer] Add new Z3 constraint manager backend Summary: Implement new Z3 constraint manager backend. Reviewers: zaks.anna, dcoughlin, NoQ, xazax.hun Subscribers: mgorny, cfe-commits Differential Revision: https://reviews.llvm.org/D28952 Added: cfe/trunk/cmake/modules/FindZ3.cmake cfe/trunk/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp cfe/trunk/test/Analysis/unsupported-types.c Modified: cfe/trunk/CMakeLists.txt cfe/trunk/include/clang/Config/config.h.cmake cfe/trunk/include/clang/StaticAnalyzer/Core/Analyses.def cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt cfe/trunk/test/Analysis/expr-inspection.c cfe/trunk/test/Analysis/lit.local.cfg cfe/trunk/test/lit.cfg cfe/trunk/test/lit.site.cfg.in Modified: cfe/trunk/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CMakeLists.txt?rev=299463&r1=299462&r2=299463&view=diff == --- cfe/trunk/CMakeLists.txt (original) +++ cfe/trunk/CMakeLists.txt Tue Apr 4 14:52:25 2017 @@ -186,6 +186,8 @@ if (LIBXML2_FOUND) set(CLANG_HAVE_LIBXML 1) endif() +find_package(Z3 4.5) + include(CheckIncludeFile) check_include_file(sys/resource.h CLANG_HAVE_RLIMITS) @@ -330,10 +332,6 @@ if (APPLE) endif() endif() -configure_file( - ${CLANG_SOURCE_DIR}/include/clang/Config/config.h.cmake - ${CLANG_BINARY_DIR}/include/clang/Config/config.h) - include(CMakeParseArguments) include(AddClang) @@ -371,8 +369,19 @@ option(CLANG_BUILD_TOOLS option(CLANG_ENABLE_ARCMT "Build ARCMT." ON) option(CLANG_ENABLE_STATIC_ANALYZER "Build static analyzer." ON) -if (NOT CLANG_ENABLE_STATIC_ANALYZER AND CLANG_ENABLE_ARCMT) - message(FATAL_ERROR "Cannot disable static analyzer while enabling ARCMT") +option(CLANG_ANALYZER_BUILD_Z3 + "Build the static analyzer with the Z3 constraint manager." OFF) + +if(NOT CLANG_ENABLE_STATIC_ANALYZER AND (CLANG_ENABLE_ARCMT OR CLANG_ANALYZER_BUILD_Z3)) + message(FATAL_ERROR "Cannot disable static analyzer while enabling ARCMT or Z3") +endif() + +if(CLANG_ANALYZER_BUILD_Z3) + if(Z3_FOUND) +set(CLANG_ANALYZER_WITH_Z3 1) + else() +message(FATAL_ERROR "Cannot find Z3 header file or shared library") + endif() endif() if(CLANG_ENABLE_ARCMT) @@ -687,3 +696,7 @@ endif() if (LLVM_ADD_NATIVE_VISUALIZERS_TO_SOLUTION) add_subdirectory(utils/ClangVisualizers) endif() + +configure_file( + ${CLANG_SOURCE_DIR}/include/clang/Config/config.h.cmake + ${CLANG_BINARY_DIR}/include/clang/Config/config.h) Added: cfe/trunk/cmake/modules/FindZ3.cmake URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/cmake/modules/FindZ3.cmake?rev=299463&view=auto == --- cfe/trunk/cmake/modules/FindZ3.cmake (added) +++ cfe/trunk/cmake/modules/FindZ3.cmake Tue Apr 4 14:52:25 2017 @@ -0,0 +1,28 @@ +find_path(Z3_INCLUDE_DIR NAMES z3.h + PATH_SUFFIXES libz3 + ) + +find_library(Z3_LIBRARIES NAMES z3 libz3 + ) + +find_program(Z3_EXECUTABLE z3) + +if(Z3_INCLUDE_DIR AND Z3_EXECUTABLE) +execute_process (COMMAND ${Z3_EXECUTABLE} -version + OUTPUT_VARIABLE libz3_version_str + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + +string(REGEX REPLACE "^Z3 version ([0-9.]+)" "\\1" + Z3_VERSION_STRING "${libz3_version_str}") +unset(libz3_version_str) +endif() + +# handle the QUIETLY and REQUIRED arguments and set Z3_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Z3 + REQUIRED_VARS Z3_LIBRARIES Z3_INCLUDE_DIR + VERSION_VAR Z3_VERSION_STRING) + +mark_as_advanced(Z3_INCLUDE_DIR Z3_LIBRARIES) Modified: cfe/trunk/include/clang/Config/config.h.cmake URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Config/config.h.cmake?rev=299463&r1=299462&r2=299463&view=diff == --- cfe/trunk/include/clang/Config/config.h.cmake (original) +++ cfe/trunk/include/clang/Config/config.h.cmake Tue Apr 4 14:52:25 2017 @@ -38,6 +38,9 @@ /* Define if we have libxml2 */ #cmakedefine CLANG_HAVE_LIBXML ${CLANG_HAVE_LIBXML} +/* Define if we have z3 and want to build it */ +#cmakedefine CLANG_ANALYZER_WITH_Z3 ${CLANG_ANALYZER_WITH_Z3} + /* Define if we have sys/resource.h (rlimits) */ #cmakedefine CLANG_HAVE_RLIMITS ${CLANG_HAVE_RLIMITS} Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/Analyses.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/Analyses.def?rev=299463&r1=299462&r2=299463&view=diff ===
[PATCH] D28952: [analyzer] Add new Z3 constraint manager backend
This revision was automatically updated to reflect the committed changes. Closed by commit rL299463: [analyzer] Add new Z3 constraint manager backend (authored by ddcc). Changed prior to commit: https://reviews.llvm.org/D28952?vs=93974&id=94107#toc Repository: rL LLVM https://reviews.llvm.org/D28952 Files: cfe/trunk/CMakeLists.txt cfe/trunk/cmake/modules/FindZ3.cmake cfe/trunk/include/clang/Config/config.h.cmake cfe/trunk/include/clang/StaticAnalyzer/Core/Analyses.def cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt cfe/trunk/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp cfe/trunk/test/Analysis/expr-inspection.c cfe/trunk/test/Analysis/lit.local.cfg cfe/trunk/test/Analysis/unsupported-types.c cfe/trunk/test/lit.cfg cfe/trunk/test/lit.site.cfg.in Index: cfe/trunk/include/clang/Config/config.h.cmake === --- cfe/trunk/include/clang/Config/config.h.cmake +++ cfe/trunk/include/clang/Config/config.h.cmake @@ -38,6 +38,9 @@ /* Define if we have libxml2 */ #cmakedefine CLANG_HAVE_LIBXML ${CLANG_HAVE_LIBXML} +/* Define if we have z3 and want to build it */ +#cmakedefine CLANG_ANALYZER_WITH_Z3 ${CLANG_ANALYZER_WITH_Z3} + /* Define if we have sys/resource.h (rlimits) */ #cmakedefine CLANG_HAVE_RLIMITS ${CLANG_HAVE_RLIMITS} Index: cfe/trunk/include/clang/StaticAnalyzer/Core/Analyses.def === --- cfe/trunk/include/clang/StaticAnalyzer/Core/Analyses.def +++ cfe/trunk/include/clang/StaticAnalyzer/Core/Analyses.def @@ -22,6 +22,7 @@ #endif ANALYSIS_CONSTRAINTS(RangeConstraints, "range", "Use constraint tracking of concrete value ranges", CreateRangeConstraintManager) +ANALYSIS_CONSTRAINTS(Z3Constraints, "z3", "Use Z3 contraint solver", CreateZ3ConstraintManager) #ifndef ANALYSIS_DIAGNOSTICS #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) Index: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h === --- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h +++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h @@ -184,6 +184,9 @@ CreateRangeConstraintManager(ProgramStateManager &statemgr, SubEngine *subengine); +std::unique_ptr +CreateZ3ConstraintManager(ProgramStateManager &statemgr, SubEngine *subengine); + } // end GR namespace } // end clang namespace Index: cfe/trunk/cmake/modules/FindZ3.cmake === --- cfe/trunk/cmake/modules/FindZ3.cmake +++ cfe/trunk/cmake/modules/FindZ3.cmake @@ -0,0 +1,28 @@ +find_path(Z3_INCLUDE_DIR NAMES z3.h + PATH_SUFFIXES libz3 + ) + +find_library(Z3_LIBRARIES NAMES z3 libz3 + ) + +find_program(Z3_EXECUTABLE z3) + +if(Z3_INCLUDE_DIR AND Z3_EXECUTABLE) +execute_process (COMMAND ${Z3_EXECUTABLE} -version + OUTPUT_VARIABLE libz3_version_str + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + +string(REGEX REPLACE "^Z3 version ([0-9.]+)" "\\1" + Z3_VERSION_STRING "${libz3_version_str}") +unset(libz3_version_str) +endif() + +# handle the QUIETLY and REQUIRED arguments and set Z3_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Z3 + REQUIRED_VARS Z3_LIBRARIES Z3_INCLUDE_DIR + VERSION_VAR Z3_VERSION_STRING) + +mark_as_advanced(Z3_INCLUDE_DIR Z3_LIBRARIES) Index: cfe/trunk/test/lit.site.cfg.in === --- cfe/trunk/test/lit.site.cfg.in +++ cfe/trunk/test/lit.site.cfg.in @@ -18,6 +18,7 @@ config.clang_arcmt = @CLANG_ENABLE_ARCMT@ config.clang_default_cxx_stdlib = "@CLANG_DEFAULT_CXX_STDLIB@" config.clang_staticanalyzer = @CLANG_ENABLE_STATIC_ANALYZER@ +config.clang_staticanalyzer_z3 = "@CLANG_ANALYZER_WITH_Z3@" config.clang_examples = @CLANG_BUILD_EXAMPLES@ config.enable_shared = @ENABLE_SHARED@ config.enable_backtrace = @ENABLE_BACKTRACES@ Index: cfe/trunk/test/lit.cfg === --- cfe/trunk/test/lit.cfg +++ cfe/trunk/test/lit.cfg @@ -361,6 +361,9 @@ if config.clang_staticanalyzer: config.available_features.add("staticanalyzer") +if config.clang_staticanalyzer_z3 == '1': +config.available_features.add("z3") + # As of 2011.08, crash-recovery tests still do not pass on FreeBSD. if platform.system() not in ['FreeBSD']: config.available_features.add('crash-recovery') Index: cfe/trunk/test/Analysis/unsupported-types.c === --- cfe/trunk/test/Analysis/unsupported-types.c +++ cfe/trunk/test/Analysis/unsupported-ty
[PATCH] D31673: Allow casting C pointers declared using extern "C" to ObjC pointer types
rjmccall added inline comments. Comment at: lib/Sema/SemaExprObjC.cpp:3358 var && - var->getStorageClass() == SC_Extern && + !var->isThisDeclarationADefinition() && var->getType().isConstQualified()) { Hmm. Come to think of it, I wonder if we actually care whether the variable has a definition, given that it's const. Well, we can consider that later. I agree that this change is good. Comment at: test/SemaObjCXX/arc-bridged-cast.mm:59 +extern "C" const CFAnnotatedObjectRef r2; +extern "C" const CFAnnotatedObjectRef r3 = 0; + These examples are a little unfortunate because these values are known to be null pointers. https://reviews.llvm.org/D31673 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r299465 - [clang-format] fix crash in NamespaceEndCommentsFixer (PR32438)
Author: mgehre Date: Tue Apr 4 15:11:13 2017 New Revision: 299465 URL: http://llvm.org/viewvc/llvm-project?rev=299465&view=rev Log: [clang-format] fix crash in NamespaceEndCommentsFixer (PR32438) Summary: The new test case was crashing before. Now it passes as expected. Reviewers: djasper Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D31441 Modified: cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp Modified: cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp?rev=299465&r1=299464&r2=299465&view=diff == --- cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp (original) +++ cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp Tue Apr 4 15:11:13 2017 @@ -133,7 +133,7 @@ tooling::Replacements NamespaceEndCommen // Detect "(inline)? namespace" in the beginning of a line. if (NamespaceTok->is(tok::kw_inline)) NamespaceTok = NamespaceTok->getNextNonComment(); -if (NamespaceTok->isNot(tok::kw_namespace)) +if (!NamespaceTok || NamespaceTok->isNot(tok::kw_namespace)) continue; FormatToken *RBraceTok = EndLine->First; if (RBraceTok->Finalized) Modified: cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp?rev=299465&r1=299464&r2=299465&view=diff == --- cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp (original) +++ cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp Tue Apr 4 15:11:13 2017 @@ -582,6 +582,21 @@ TEST_F(NamespaceEndCommentsFixerTest, "} // namespace\n" "}")); } + +TEST_F(NamespaceEndCommentsFixerTest, HandlesInlineAtEndOfLine_PR32438) { + EXPECT_EQ("template struct a {};\n" +"struct a b() {\n" +"}\n" +"#define c inline\n" +"void d() {\n" +"}\n", +fixNamespaceEndComments("template struct a {};\n" +"struct a b() {\n" +"}\n" +"#define c inline\n" +"void d() {\n" +"}\n")); +} } // end namespace } // end namespace format } // end namespace clang ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31441: [clang-format] fix crash in NamespaceEndCommentsFixer (PR32438)
This revision was automatically updated to reflect the committed changes. Closed by commit rL299465: [clang-format] fix crash in NamespaceEndCommentsFixer (PR32438) (authored by mgehre). Changed prior to commit: https://reviews.llvm.org/D31441?vs=93507&id=94108#toc Repository: rL LLVM https://reviews.llvm.org/D31441 Files: cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp Index: cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp === --- cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp +++ cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp @@ -133,7 +133,7 @@ // Detect "(inline)? namespace" in the beginning of a line. if (NamespaceTok->is(tok::kw_inline)) NamespaceTok = NamespaceTok->getNextNonComment(); -if (NamespaceTok->isNot(tok::kw_namespace)) +if (!NamespaceTok || NamespaceTok->isNot(tok::kw_namespace)) continue; FormatToken *RBraceTok = EndLine->First; if (RBraceTok->Finalized) Index: cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp === --- cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp +++ cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp @@ -582,6 +582,21 @@ "} // namespace\n" "}")); } + +TEST_F(NamespaceEndCommentsFixerTest, HandlesInlineAtEndOfLine_PR32438) { + EXPECT_EQ("template struct a {};\n" +"struct a b() {\n" +"}\n" +"#define c inline\n" +"void d() {\n" +"}\n", +fixNamespaceEndComments("template struct a {};\n" +"struct a b() {\n" +"}\n" +"#define c inline\n" +"void d() {\n" +"}\n")); +} } // end namespace } // end namespace format } // end namespace clang Index: cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp === --- cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp +++ cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp @@ -133,7 +133,7 @@ // Detect "(inline)? namespace" in the beginning of a line. if (NamespaceTok->is(tok::kw_inline)) NamespaceTok = NamespaceTok->getNextNonComment(); -if (NamespaceTok->isNot(tok::kw_namespace)) +if (!NamespaceTok || NamespaceTok->isNot(tok::kw_namespace)) continue; FormatToken *RBraceTok = EndLine->First; if (RBraceTok->Finalized) Index: cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp === --- cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp +++ cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp @@ -582,6 +582,21 @@ "} // namespace\n" "}")); } + +TEST_F(NamespaceEndCommentsFixerTest, HandlesInlineAtEndOfLine_PR32438) { + EXPECT_EQ("template struct a {};\n" +"struct a b() {\n" +"}\n" +"#define c inline\n" +"void d() {\n" +"}\n", +fixNamespaceEndComments("template struct a {};\n" +"struct a b() {\n" +"}\n" +"#define c inline\n" +"void d() {\n" +"}\n")); +} } // end namespace } // end namespace format } // end namespace clang ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31447: [Driver] Add option to print the resource directory
clm updated this revision to Diff 94110. clm added a subscriber: meadori. clm added a comment. I've now updated the patch to include your suggested revision of the test case. I don't have commit access yet, but meadori said that he would commit it for me. https://reviews.llvm.org/D31447 Files: include/clang/Driver/Options.td lib/Driver/Driver.cpp test/Driver/immediate-options.c Index: test/Driver/immediate-options.c === --- test/Driver/immediate-options.c +++ test/Driver/immediate-options.c @@ -12,3 +12,8 @@ // RUN: %clang -print-search-dirs | FileCheck %s -check-prefix=PRINT-SEARCH-DIRS // PRINT-SEARCH-DIRS: programs: ={{.*}} // PRINT-SEARCH-DIRS: libraries: ={{.*}} + +// Test if the -print-resource-dir option is accepted without error. +// Allow unspecified output because the value of CLANG_RESOURCE_DIR is unknown. +// RUN: %clang -print-resource-dir | FileCheck %s -check-prefix=PRINT-RESOURCE-DIR +// PRINT-RESOURCE-DIR: {{.+}} Index: lib/Driver/Driver.cpp === --- lib/Driver/Driver.cpp +++ lib/Driver/Driver.cpp @@ -1145,6 +1145,11 @@ if (C.getArgs().hasArg(options::OPT_v)) TC.printVerboseInfo(llvm::errs()); + if (C.getArgs().hasArg(options::OPT_print_resource_dir)) { +llvm::outs() << ResourceDir; +return false; + } + if (C.getArgs().hasArg(options::OPT_print_search_dirs)) { llvm::outs() << "programs: ="; bool separator = false; Index: include/clang/Driver/Options.td === --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1938,6 +1938,8 @@ Flags<[Unsupported]>; def print_prog_name_EQ : Joined<["-", "--"], "print-prog-name=">, HelpText<"Print the full program path of ">, MetaVarName<"">; +def print_resource_dir : Flag<["-", "--"], "print-resource-dir">, + HelpText<"Print the resource directory pathname">; def print_search_dirs : Flag<["-", "--"], "print-search-dirs">, HelpText<"Print the paths used for finding libraries and programs">; def private__bundle : Flag<["-"], "private_bundle">; Index: test/Driver/immediate-options.c === --- test/Driver/immediate-options.c +++ test/Driver/immediate-options.c @@ -12,3 +12,8 @@ // RUN: %clang -print-search-dirs | FileCheck %s -check-prefix=PRINT-SEARCH-DIRS // PRINT-SEARCH-DIRS: programs: ={{.*}} // PRINT-SEARCH-DIRS: libraries: ={{.*}} + +// Test if the -print-resource-dir option is accepted without error. +// Allow unspecified output because the value of CLANG_RESOURCE_DIR is unknown. +// RUN: %clang -print-resource-dir | FileCheck %s -check-prefix=PRINT-RESOURCE-DIR +// PRINT-RESOURCE-DIR: {{.+}} Index: lib/Driver/Driver.cpp === --- lib/Driver/Driver.cpp +++ lib/Driver/Driver.cpp @@ -1145,6 +1145,11 @@ if (C.getArgs().hasArg(options::OPT_v)) TC.printVerboseInfo(llvm::errs()); + if (C.getArgs().hasArg(options::OPT_print_resource_dir)) { +llvm::outs() << ResourceDir; +return false; + } + if (C.getArgs().hasArg(options::OPT_print_search_dirs)) { llvm::outs() << "programs: ="; bool separator = false; Index: include/clang/Driver/Options.td === --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1938,6 +1938,8 @@ Flags<[Unsupported]>; def print_prog_name_EQ : Joined<["-", "--"], "print-prog-name=">, HelpText<"Print the full program path of ">, MetaVarName<"">; +def print_resource_dir : Flag<["-", "--"], "print-resource-dir">, + HelpText<"Print the resource directory pathname">; def print_search_dirs : Flag<["-", "--"], "print-search-dirs">, HelpText<"Print the paths used for finding libraries and programs">; def private__bundle : Flag<["-"], "private_bundle">; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31568: Add Python 3 support to clang.cindex
jbcoe updated this revision to Diff 94120. jbcoe added a comment. Remove a couple of unnecessary type conversions. Repository: rL LLVM https://reviews.llvm.org/D31568 Files: clang/bindings/python/clang/__init__.py clang/bindings/python/clang/cindex.py clang/bindings/python/tests/cindex/test_translation_unit.py Index: clang/bindings/python/tests/cindex/test_translation_unit.py === --- clang/bindings/python/tests/cindex/test_translation_unit.py +++ clang/bindings/python/tests/cindex/test_translation_unit.py @@ -59,9 +59,12 @@ assert spellings[-1] == 'y' def test_unsaved_files_2(): -import StringIO +try: +from StringIO import StringIO +except: +from io import StringIO tu = TranslationUnit.from_source('fake.c', unsaved_files = [ -('fake.c', StringIO.StringIO('int x;'))]) +('fake.c', StringIO('int x;'))]) spellings = [c.spelling for c in tu.cursor.get_children()] assert spellings[-1] == 'x' Index: clang/bindings/python/clang/cindex.py === --- clang/bindings/python/clang/cindex.py +++ clang/bindings/python/clang/cindex.py @@ -67,6 +67,60 @@ import clang.enumerations +import sys +if sys.version_info[0] == 3: +# Python 3 strings are unicode, translate them to/from utf8 for C-interop. +class c_interop_string(c_char_p): + +def __init__(self, p=None): +if p is None: +p = "" +if isinstance(p, str): +p = p.encode("utf8") +super(c_char_p, self).__init__(p) + +def __str__(self): +return self.value + +@property +def value(self): +if super(c_char_p, self).value is None: +return None +return super(c_char_p, self).value.decode("utf8") + +@classmethod +def from_param(cls, param): +if isinstance(param, str): +return cls(param) +if isinstance(param, bytes): +return cls(param) +raise TypeError("Cannot convert '{}' to '{}'".format(type(param).__name__, cls.__name__)) + +@staticmethod +def to_python_string(x, *args): +return x.value + +def b(x): +if isinstance(x, bytes): +return x +return x.encode('utf8') + +xrange = range + +elif sys.version_info[0] == 2: +# Python 2 strings are utf8 byte strings, no translation is needed for +# C-interop. +c_interop_string = c_char_p + +def _to_python_string(x, *args): +return x + +c_interop_string.to_python_string = staticmethod(_to_python_string) + +def b(x): +return x + + # ctypes doesn't implicitly convert c_void_p to the appropriate wrapper # object. This is a problem, because it means that from_parameter will see an # integer and pass the wrong value on platforms where int != void*. Work around @@ -157,6 +211,7 @@ assert isinstance(res, _CXString) return conf.lib.clang_getCString(res) + class SourceLocation(Structure): """ A SourceLocation represents a particular location within a source file. @@ -596,7 +651,7 @@ @staticmethod def get_all_kinds(): """Return all CursorKind enumeration instances.""" -return filter(None, CursorKind._kinds) +return [x for x in CursorKind._kinds if not x is None] def is_declaration(self): """Test if this is a declaration kind.""" @@ -2128,7 +2183,7 @@ """ Retrieve the offset of a field in the record. """ -return conf.lib.clang_Type_getOffsetOf(self, c_char_p(fieldname)) +return conf.lib.clang_Type_getOffsetOf(self, fieldname) def get_ref_qualifier(self): """ @@ -2239,7 +2294,7 @@ def spelling(self): if self.__kindNumber in SpellingCache: return SpellingCache[self.__kindNumber] -return conf.lib.clang_getCompletionChunkText(self.cs, self.key).spelling +return conf.lib.clang_getCompletionChunkText(self.cs, self.key) # We do not use @CachedProperty here, as the manual implementation is # apparently still significantly faster. Please profile carefully if you @@ -2345,7 +2400,7 @@ return " | ".join([str(a) for a in self]) \ + " || Priority: " + str(self.priority) \ + " || Availability: " + str(self.availability) \ - + " || Brief comment: " + str(self.briefComment.spelling) + + " || Brief comment: " + str(self.briefComment) availabilityKinds = { 0: CompletionChunk.Kind("Available"), @@ -2542,17 +2597,17 @@ args_array = None if len(args) > 0: -args_array = (c_char_p * len(args))(* args) +args_array = (c_char_p * len(args))(*[b(x) for x in args]) unsaved_array = None
r299469 - Set FMF for -ffp-contract=fast
Author: anemet Date: Tue Apr 4 16:18:30 2017 New Revision: 299469 URL: http://llvm.org/viewvc/llvm-project?rev=299469&view=rev Log: Set FMF for -ffp-contract=fast With this, FMF(contract) becomes an alternative way to express the request to contract. These are currently only propagated for FMul, FAdd and FSub. The rest will be added as more FMFs are hooked up for this. This is toward fixing PR25721. Differential Revision: https://reviews.llvm.org/D31168 Added: cfe/trunk/test/CodeGen/ffp-contract-fast-option.cpp Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=299469&r1=299468&r2=299469&view=diff == --- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Tue Apr 4 16:18:30 2017 @@ -113,6 +113,22 @@ static bool CanElideOverflowCheck(const (2 * Ctx.getTypeSize(RHSTy)) < PromotedSize; } +/// Update the FastMathFlags of LLVM IR from the FPOptions in LangOptions. +static void updateFastMathFlags(llvm::FastMathFlags &FMF, +FPOptions FPFeatures) { + FMF.setAllowContract(FPFeatures.allowFPContractAcrossStatement()); +} + +/// Propagate fast-math flags from \p Op to the instruction in \p V. +static Value *propagateFMFlags(Value *V, const BinOpInfo &Op) { + if (auto *I = dyn_cast(V)) { +llvm::FastMathFlags FMF = I->getFastMathFlags(); +updateFastMathFlags(FMF, Op.FPFeatures); +I->setFastMathFlags(FMF); + } + return V; +} + class ScalarExprEmitter : public StmtVisitor { CodeGenFunction &CGF; @@ -553,8 +569,10 @@ public: !CanElideOverflowCheck(CGF.getContext(), Ops)) return EmitOverflowCheckedBinOp(Ops); -if (Ops.LHS->getType()->isFPOrFPVectorTy()) - return Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul"); +if (Ops.LHS->getType()->isFPOrFPVectorTy()) { + Value *V = Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul"); + return propagateFMFlags(V, Ops); +} return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul"); } /// Create a binary op that checks for overflow. @@ -2722,7 +2740,8 @@ Value *ScalarExprEmitter::EmitAdd(const if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder)) return FMulAdd; -return Builder.CreateFAdd(op.LHS, op.RHS, "add"); +Value *V = Builder.CreateFAdd(op.LHS, op.RHS, "add"); +return propagateFMFlags(V, op); } return Builder.CreateAdd(op.LHS, op.RHS, "add"); @@ -2755,7 +2774,8 @@ Value *ScalarExprEmitter::EmitSub(const // Try to form an fmuladd. if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder, true)) return FMulAdd; - return Builder.CreateFSub(op.LHS, op.RHS, "sub"); + Value *V = Builder.CreateFSub(op.LHS, op.RHS, "sub"); + return propagateFMFlags(V, op); } return Builder.CreateSub(op.LHS, op.RHS, "sub"); Added: cfe/trunk/test/CodeGen/ffp-contract-fast-option.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ffp-contract-fast-option.cpp?rev=299469&view=auto == --- cfe/trunk/test/CodeGen/ffp-contract-fast-option.cpp (added) +++ cfe/trunk/test/CodeGen/ffp-contract-fast-option.cpp Tue Apr 4 16:18:30 2017 @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -O3 -ffp-contract=fast -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s + +float fp_contract_1(float a, float b, float c) { + // CHECK-LABEL: fp_contract_1fff( + // CHECK: fmul contract float + // CHECK: fadd contract float + return a * b + c; +} + +float fp_contract_2(float a, float b, float c) { + // CHECK-LABEL: fp_contract_2fff( + // CHECK: fmul contract float + // CHECK: fsub contract float + return a * b - c; +} + +void fp_contract_3(float *a, float b, float c) { + // CHECK-LABEL: fp_contract_3Pfff( + // CHECK: fmul contract float + // CHECK: fadd contract float + a[0] += b * c; +} + +void fp_contract_4(float *a, float b, float c) { + // CHECK-LABEL: fp_contract_4Pfff( + // CHECK: fmul contract float + // CHECK: fsub contract float + a[0] -= b * c; +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31168: Set FMF for -ffp-contract=fast
This revision was automatically updated to reflect the committed changes. Closed by commit rL299469: Set FMF for -ffp-contract=fast (authored by anemet). Changed prior to commit: https://reviews.llvm.org/D31168?vs=93882&id=94121#toc Repository: rL LLVM https://reviews.llvm.org/D31168 Files: cfe/trunk/lib/CodeGen/CGExprScalar.cpp cfe/trunk/test/CodeGen/ffp-contract-fast-option.cpp Index: cfe/trunk/test/CodeGen/ffp-contract-fast-option.cpp === --- cfe/trunk/test/CodeGen/ffp-contract-fast-option.cpp +++ cfe/trunk/test/CodeGen/ffp-contract-fast-option.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -O3 -ffp-contract=fast -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s + +float fp_contract_1(float a, float b, float c) { + // CHECK-LABEL: fp_contract_1fff( + // CHECK: fmul contract float + // CHECK: fadd contract float + return a * b + c; +} + +float fp_contract_2(float a, float b, float c) { + // CHECK-LABEL: fp_contract_2fff( + // CHECK: fmul contract float + // CHECK: fsub contract float + return a * b - c; +} + +void fp_contract_3(float *a, float b, float c) { + // CHECK-LABEL: fp_contract_3Pfff( + // CHECK: fmul contract float + // CHECK: fadd contract float + a[0] += b * c; +} + +void fp_contract_4(float *a, float b, float c) { + // CHECK-LABEL: fp_contract_4Pfff( + // CHECK: fmul contract float + // CHECK: fsub contract float + a[0] -= b * c; +} Index: cfe/trunk/lib/CodeGen/CGExprScalar.cpp === --- cfe/trunk/lib/CodeGen/CGExprScalar.cpp +++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp @@ -113,6 +113,22 @@ (2 * Ctx.getTypeSize(RHSTy)) < PromotedSize; } +/// Update the FastMathFlags of LLVM IR from the FPOptions in LangOptions. +static void updateFastMathFlags(llvm::FastMathFlags &FMF, +FPOptions FPFeatures) { + FMF.setAllowContract(FPFeatures.allowFPContractAcrossStatement()); +} + +/// Propagate fast-math flags from \p Op to the instruction in \p V. +static Value *propagateFMFlags(Value *V, const BinOpInfo &Op) { + if (auto *I = dyn_cast(V)) { +llvm::FastMathFlags FMF = I->getFastMathFlags(); +updateFastMathFlags(FMF, Op.FPFeatures); +I->setFastMathFlags(FMF); + } + return V; +} + class ScalarExprEmitter : public StmtVisitor { CodeGenFunction &CGF; @@ -553,8 +569,10 @@ !CanElideOverflowCheck(CGF.getContext(), Ops)) return EmitOverflowCheckedBinOp(Ops); -if (Ops.LHS->getType()->isFPOrFPVectorTy()) - return Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul"); +if (Ops.LHS->getType()->isFPOrFPVectorTy()) { + Value *V = Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul"); + return propagateFMFlags(V, Ops); +} return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul"); } /// Create a binary op that checks for overflow. @@ -2722,7 +2740,8 @@ if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder)) return FMulAdd; -return Builder.CreateFAdd(op.LHS, op.RHS, "add"); +Value *V = Builder.CreateFAdd(op.LHS, op.RHS, "add"); +return propagateFMFlags(V, op); } return Builder.CreateAdd(op.LHS, op.RHS, "add"); @@ -2755,7 +2774,8 @@ // Try to form an fmuladd. if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder, true)) return FMulAdd; - return Builder.CreateFSub(op.LHS, op.RHS, "sub"); + Value *V = Builder.CreateFSub(op.LHS, op.RHS, "sub"); + return propagateFMFlags(V, op); } return Builder.CreateSub(op.LHS, op.RHS, "sub"); Index: cfe/trunk/test/CodeGen/ffp-contract-fast-option.cpp === --- cfe/trunk/test/CodeGen/ffp-contract-fast-option.cpp +++ cfe/trunk/test/CodeGen/ffp-contract-fast-option.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -O3 -ffp-contract=fast -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s + +float fp_contract_1(float a, float b, float c) { + // CHECK-LABEL: fp_contract_1fff( + // CHECK: fmul contract float + // CHECK: fadd contract float + return a * b + c; +} + +float fp_contract_2(float a, float b, float c) { + // CHECK-LABEL: fp_contract_2fff( + // CHECK: fmul contract float + // CHECK: fsub contract float + return a * b - c; +} + +void fp_contract_3(float *a, float b, float c) { + // CHECK-LABEL: fp_contract_3Pfff( + // CHECK: fmul contract float + // CHECK: fadd contract float + a[0] += b * c; +} + +void fp_contract_4(float *a, float b, float c) { + // CHECK-LABEL: fp_contract_4Pfff( + // CHECK: fmul contract float + // CHECK: fsub contract float + a[0] -= b * c; +} Index: cfe/trunk/lib/CodeGen/CGExprScalar.cpp === --- cfe/trunk/lib/CodeGen/CGExprScalar.cpp +++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp @@ -113,6 +113,22 @@ (2 * Ctx.getTypeSize(RHSTy)) < PromotedSize; } +/// Update the FastMathFlags of LL
[PATCH] D31276: Add #pragma clang fp
This revision was automatically updated to reflect the committed changes. Closed by commit rL299470: Add #pragma clang fp (authored by anemet). Changed prior to commit: https://reviews.llvm.org/D31276?vs=93325&id=94122#toc Repository: rL LLVM https://reviews.llvm.org/D31276 Files: cfe/trunk/docs/LanguageExtensions.rst cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td cfe/trunk/include/clang/Basic/TokenKinds.def cfe/trunk/include/clang/Parse/Parser.h cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Parse/ParsePragma.cpp cfe/trunk/lib/Parse/ParseStmt.cpp cfe/trunk/lib/Parse/Parser.cpp cfe/trunk/lib/Sema/SemaAttr.cpp cfe/trunk/test/CodeGen/fp-contract-fast-pragma.cpp cfe/trunk/test/CodeGen/fp-contract-on-pragma.cpp cfe/trunk/test/Parser/cxx11-stmt-attributes.cpp cfe/trunk/test/Parser/pragma-fp.cpp Index: cfe/trunk/test/Parser/pragma-fp.cpp === --- cfe/trunk/test/Parser/pragma-fp.cpp +++ cfe/trunk/test/Parser/pragma-fp.cpp @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +void test_0(int *List, int Length) { +/* expected-error@+1 {{missing option; expected contract}} */ +#pragma clang fp + for (int i = 0; i < Length; i++) { +List[i] = i; + } +} +void test_1(int *List, int Length) { +/* expected-error@+1 {{invalid option 'blah'; expected contract}} */ +#pragma clang fp blah + for (int i = 0; i < Length; i++) { +List[i] = i; + } +} + +void test_3(int *List, int Length) { +/* expected-error@+1 {{expected '('}} */ +#pragma clang fp contract on + for (int i = 0; i < Length; i++) { +List[i] = i; + } +} + +void test_4(int *List, int Length) { +/* expected-error@+1 {{unexpected argument 'while' to '#pragma clang fp contract'; expected 'on', 'fast' or 'off'}} */ +#pragma clang fp contract(while) + for (int i = 0; i < Length; i++) { +List[i] = i; + } +} + +void test_5(int *List, int Length) { +/* expected-error@+1 {{unexpected argument 'maybe' to '#pragma clang fp contract'; expected 'on', 'fast' or 'off'}} */ +#pragma clang fp contract(maybe) + for (int i = 0; i < Length; i++) { +List[i] = i; + } +} + +void test_6(int *List, int Length) { +/* expected-error@+1 {{expected ')'}} */ +#pragma clang fp contract(fast + for (int i = 0; i < Length; i++) { +List[i] = i; + } +} + +void test_7(int *List, int Length) { +/* expected-warning@+1 {{extra tokens at end of '#pragma clang fp' - ignored}} */ +#pragma clang fp contract(fast) * + for (int i = 0; i < Length; i++) { +List[i] = i; + } +} + +void test_8(int *List, int Length) { + for (int i = 0; i < Length; i++) { +List[i] = i; +/* expected-error@+1 {{'#pragma clang fp' can only appear at file scope or at the start of a compound statement}} */ +#pragma clang fp contract(fast) + } +} Index: cfe/trunk/test/Parser/cxx11-stmt-attributes.cpp === --- cfe/trunk/test/Parser/cxx11-stmt-attributes.cpp +++ cfe/trunk/test/Parser/cxx11-stmt-attributes.cpp @@ -80,5 +80,6 @@ { [[ ]] // expected-error {{an attribute list cannot appear here}} #pragma STDC FP_CONTRACT ON // expected-error {{can only appear at file scope or at the start of a compound statement}} +#pragma clang fp contract(fast) // expected-error {{can only appear at file scope or at the start of a compound statement}} } } Index: cfe/trunk/test/CodeGen/fp-contract-fast-pragma.cpp === --- cfe/trunk/test/CodeGen/fp-contract-fast-pragma.cpp +++ cfe/trunk/test/CodeGen/fp-contract-fast-pragma.cpp @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s + +// Is FP_CONTRACT honored in a simple case? +float fp_contract_1(float a, float b, float c) { +// CHECK: _Z13fp_contract_1fff +// CHECK: %[[M:.+]] = fmul contract float %a, %b +// CHECK-NEXT: fadd contract float %[[M]], %c +#pragma clang fp contract(fast) + return a * b + c; +} + +// Is FP_CONTRACT state cleared on exiting compound statements? +float fp_contract_2(float a, float b, float c) { + // CHECK: _Z13fp_contract_2fff + // CHECK: %[[M:.+]] = fmul float %a, %b + // CHECK-NEXT: fadd float %[[M]], %c + { +#pragma clang fp contract(fast) + } + return a * b + c; +} + +// Does FP_CONTRACT survive template instantiation? +class Foo {}; +Foo operator+(Foo, Foo); + +template +T template_muladd(T a, T b, T c) { +#pragma clang fp contract(fast) + return a * b + c; +} + +float fp_contract_3(float a, float b, float c) { + // CHECK: _Z13fp_contract_3fff + // CHECK: %[[M:.+]] = fmul contract float %a, %b + // CHECK-NEXT: fadd contract float %[[M]], %c + return template_muladd(a, b, c); +} + +template +class fp_contract_4 { + float method(float a, float b, float c) { +#pragma clang fp contract(fast) +return a * b + c; + } +}; + +template class fp_contract_4; +// CHECK: _ZN13fp_contract_4IiE6methodEfff +// CHECK: %[[M:.+]] = fmul
r299470 - Add #pragma clang fp
Author: anemet Date: Tue Apr 4 16:18:36 2017 New Revision: 299470 URL: http://llvm.org/viewvc/llvm-project?rev=299470&view=rev Log: Add #pragma clang fp This adds the new pragma and the first variant, contract(on/off/fast). The pragma has the same block scope rules as STDC FP_CONTRACT, i.e. it can be placed at the beginning of a compound statement or at file scope. Similarly to STDC FP_CONTRACT there is no need to use attributes. First an annotate token is inserted with the parsed details of the pragma. Then the annotate token is parsed in the proper contexts and the Sema is updated with the corresponding FPOptions using the shared ActOn function with STDC FP_CONTRACT. After this the FPOptions from the Sema is propagated into the AST expression nodes. There is no change here. I was going to add a 'default' option besides 'on/off/fast' similar to STDC FP_CONTRACT but then decided against it. I think that we'd have to make option uppercase then to avoid using 'default' the keyword. Also because of the scoped activation of pragma I am not sure there is really a need a for this. Differential Revision: https://reviews.llvm.org/D31276 Added: cfe/trunk/test/CodeGen/fp-contract-fast-pragma.cpp cfe/trunk/test/CodeGen/fp-contract-on-pragma.cpp cfe/trunk/test/Parser/pragma-fp.cpp Modified: cfe/trunk/docs/LanguageExtensions.rst cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td cfe/trunk/include/clang/Basic/TokenKinds.def cfe/trunk/include/clang/Parse/Parser.h cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Parse/ParsePragma.cpp cfe/trunk/lib/Parse/ParseStmt.cpp cfe/trunk/lib/Parse/Parser.cpp cfe/trunk/lib/Sema/SemaAttr.cpp cfe/trunk/test/Parser/cxx11-stmt-attributes.cpp Modified: cfe/trunk/docs/LanguageExtensions.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=299470&r1=299469&r2=299470&view=diff == --- cfe/trunk/docs/LanguageExtensions.rst (original) +++ cfe/trunk/docs/LanguageExtensions.rst Tue Apr 4 16:18:36 2017 @@ -2312,3 +2312,36 @@ For example, the hint ``vectorize_width( proven safe to vectorize. To identify and diagnose optimization issues use `-Rpass`, `-Rpass-missed`, and `-Rpass-analysis` command line options. See the user guide for details. + +Extensions to specify floating-point flags + + +The ``#pragma clang fp`` pragma allows floating-point options to be specified +for a section of the source code. This pragma can only appear at file scope or +at the start of a compound statement (excluding comments). When using within a +compound statement, the pragma is active within the scope of the compound +statement. + +Currently, only FP contraction can be controlled with the pragma. ``#pragma +clang fp contract`` specifies whether the compiler should contract a multiply +and an addition (or subtraction) into a fused FMA operation when supported by +the target. + +The pragma can take three values: ``on``, ``fast`` and ``off``. The ``on`` +option is identical to using ``#pragma STDC FP_CONTRACT(ON)`` and it allows +fusion as specified the language standard. The ``fast`` option allows fusiong +in cases when the language standard does not make this possible (e.g. across +statements in C) + +.. code-block:: c++ + + for(...) { +#pragma clang fp contract(fast) +a = b[i] * c[i]; +d[i] += a; + } + + +The pragma can also be used with 'off' which turns FP contraction off for a +section of the code. This can be useful when fast contraction is otherwise +enabled for the translation unit with the ``-ffp-contract=fast` flag. Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=299470&r1=299469&r2=299470&view=diff == --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Tue Apr 4 16:18:36 2017 @@ -1040,6 +1040,16 @@ def err_pragma_loop_missing_argument : E def err_pragma_loop_invalid_option : Error< "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, " "vectorize_width, interleave, interleave_count, unroll, unroll_count, or distribute">; + +def err_pragma_fp_invalid_option : Error< + "%select{invalid|missing}0 option%select{ %1|}0; expected contract">; +def err_pragma_fp_invalid_argument : Error< + "unexpected argument '%0' to '#pragma clang fp %1'; " + "expected 'on', 'fast' or 'off'">; +def err_pragma_fp_scope : Error< + "'#pragma clang fp' can only appear at file scope or at the start of a " + "compound statement">; + def err_pragma_invalid_keyword : Error< "invalid argument; expected 'enable'%select{|, 'full'}0%select{|, 'assume_safety'}1 or 'disable'">; Modified: cfe/trun
r299473 - [Driver] Add option to print the resource directory
Author: meadori Date: Tue Apr 4 16:46:50 2017 New Revision: 299473 URL: http://llvm.org/viewvc/llvm-project?rev=299473&view=rev Log: [Driver] Add option to print the resource directory This patch adds the option -print-resource-dir. It simply prints the resource directory. This information will eventually be used in compiler-rt to setup COMPILER_RT_LIBRARY_INSTALL_DIR. Patch by Catherine Moore! Differential Revision: https://reviews.llvm.org/D31447 Modified: cfe/trunk/include/clang/Driver/Options.td cfe/trunk/lib/Driver/Driver.cpp cfe/trunk/test/Driver/immediate-options.c Modified: cfe/trunk/include/clang/Driver/Options.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=299473&r1=299472&r2=299473&view=diff == --- cfe/trunk/include/clang/Driver/Options.td (original) +++ cfe/trunk/include/clang/Driver/Options.td Tue Apr 4 16:46:50 2017 @@ -2091,6 +2091,8 @@ def print_multi_os_directory : Flag<["-" Flags<[Unsupported]>; def print_prog_name_EQ : Joined<["-", "--"], "print-prog-name=">, HelpText<"Print the full program path of ">, MetaVarName<"">; +def print_resource_dir : Flag<["-", "--"], "print-resource-dir">, + HelpText<"Print the resource directory pathname">; def print_search_dirs : Flag<["-", "--"], "print-search-dirs">, HelpText<"Print the paths used for finding libraries and programs">; def private__bundle : Flag<["-"], "private_bundle">; Modified: cfe/trunk/lib/Driver/Driver.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=299473&r1=299472&r2=299473&view=diff == --- cfe/trunk/lib/Driver/Driver.cpp (original) +++ cfe/trunk/lib/Driver/Driver.cpp Tue Apr 4 16:46:50 2017 @@ -1169,6 +1169,11 @@ bool Driver::HandleImmediateArgs(const C if (C.getArgs().hasArg(options::OPT_v)) TC.printVerboseInfo(llvm::errs()); + if (C.getArgs().hasArg(options::OPT_print_resource_dir)) { +llvm::outs() << ResourceDir; +return false; + } + if (C.getArgs().hasArg(options::OPT_print_search_dirs)) { llvm::outs() << "programs: ="; bool separator = false; Modified: cfe/trunk/test/Driver/immediate-options.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/immediate-options.c?rev=299473&r1=299472&r2=299473&view=diff == --- cfe/trunk/test/Driver/immediate-options.c (original) +++ cfe/trunk/test/Driver/immediate-options.c Tue Apr 4 16:46:50 2017 @@ -12,3 +12,8 @@ // RUN: %clang -print-search-dirs | FileCheck %s -check-prefix=PRINT-SEARCH-DIRS // PRINT-SEARCH-DIRS: programs: ={{.*}} // PRINT-SEARCH-DIRS: libraries: ={{.*}} + +// Test if the -print-resource-dir option is accepted without error. +// Allow unspecified output because the value of CLANG_RESOURCE_DIR is unknown. +// RUN: %clang -print-resource-dir | FileCheck %s -check-prefix=PRINT-RESOURCE-DIR +// PRINT-RESOURCE-DIR: {{.+}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31447: [Driver] Add option to print the resource directory
This revision was automatically updated to reflect the committed changes. Closed by commit rL299473: [Driver] Add option to print the resource directory (authored by meadori). Changed prior to commit: https://reviews.llvm.org/D31447?vs=94110&id=94126#toc Repository: rL LLVM https://reviews.llvm.org/D31447 Files: cfe/trunk/include/clang/Driver/Options.td cfe/trunk/lib/Driver/Driver.cpp cfe/trunk/test/Driver/immediate-options.c Index: cfe/trunk/include/clang/Driver/Options.td === --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -2091,6 +2091,8 @@ Flags<[Unsupported]>; def print_prog_name_EQ : Joined<["-", "--"], "print-prog-name=">, HelpText<"Print the full program path of ">, MetaVarName<"">; +def print_resource_dir : Flag<["-", "--"], "print-resource-dir">, + HelpText<"Print the resource directory pathname">; def print_search_dirs : Flag<["-", "--"], "print-search-dirs">, HelpText<"Print the paths used for finding libraries and programs">; def private__bundle : Flag<["-"], "private_bundle">; Index: cfe/trunk/test/Driver/immediate-options.c === --- cfe/trunk/test/Driver/immediate-options.c +++ cfe/trunk/test/Driver/immediate-options.c @@ -12,3 +12,8 @@ // RUN: %clang -print-search-dirs | FileCheck %s -check-prefix=PRINT-SEARCH-DIRS // PRINT-SEARCH-DIRS: programs: ={{.*}} // PRINT-SEARCH-DIRS: libraries: ={{.*}} + +// Test if the -print-resource-dir option is accepted without error. +// Allow unspecified output because the value of CLANG_RESOURCE_DIR is unknown. +// RUN: %clang -print-resource-dir | FileCheck %s -check-prefix=PRINT-RESOURCE-DIR +// PRINT-RESOURCE-DIR: {{.+}} Index: cfe/trunk/lib/Driver/Driver.cpp === --- cfe/trunk/lib/Driver/Driver.cpp +++ cfe/trunk/lib/Driver/Driver.cpp @@ -1169,6 +1169,11 @@ if (C.getArgs().hasArg(options::OPT_v)) TC.printVerboseInfo(llvm::errs()); + if (C.getArgs().hasArg(options::OPT_print_resource_dir)) { +llvm::outs() << ResourceDir; +return false; + } + if (C.getArgs().hasArg(options::OPT_print_search_dirs)) { llvm::outs() << "programs: ="; bool separator = false; Index: cfe/trunk/include/clang/Driver/Options.td === --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -2091,6 +2091,8 @@ Flags<[Unsupported]>; def print_prog_name_EQ : Joined<["-", "--"], "print-prog-name=">, HelpText<"Print the full program path of ">, MetaVarName<"">; +def print_resource_dir : Flag<["-", "--"], "print-resource-dir">, + HelpText<"Print the resource directory pathname">; def print_search_dirs : Flag<["-", "--"], "print-search-dirs">, HelpText<"Print the paths used for finding libraries and programs">; def private__bundle : Flag<["-"], "private_bundle">; Index: cfe/trunk/test/Driver/immediate-options.c === --- cfe/trunk/test/Driver/immediate-options.c +++ cfe/trunk/test/Driver/immediate-options.c @@ -12,3 +12,8 @@ // RUN: %clang -print-search-dirs | FileCheck %s -check-prefix=PRINT-SEARCH-DIRS // PRINT-SEARCH-DIRS: programs: ={{.*}} // PRINT-SEARCH-DIRS: libraries: ={{.*}} + +// Test if the -print-resource-dir option is accepted without error. +// Allow unspecified output because the value of CLANG_RESOURCE_DIR is unknown. +// RUN: %clang -print-resource-dir | FileCheck %s -check-prefix=PRINT-RESOURCE-DIR +// PRINT-RESOURCE-DIR: {{.+}} Index: cfe/trunk/lib/Driver/Driver.cpp === --- cfe/trunk/lib/Driver/Driver.cpp +++ cfe/trunk/lib/Driver/Driver.cpp @@ -1169,6 +1169,11 @@ if (C.getArgs().hasArg(options::OPT_v)) TC.printVerboseInfo(llvm::errs()); + if (C.getArgs().hasArg(options::OPT_print_resource_dir)) { +llvm::outs() << ResourceDir; +return false; + } + if (C.getArgs().hasArg(options::OPT_print_search_dirs)) { llvm::outs() << "programs: ="; bool separator = false; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r299481 - Fix sphinx warning from r299470
Author: anemet Date: Tue Apr 4 17:45:20 2017 New Revision: 299481 URL: http://llvm.org/viewvc/llvm-project?rev=299481&view=rev Log: Fix sphinx warning from r299470 Modified: cfe/trunk/docs/LanguageExtensions.rst Modified: cfe/trunk/docs/LanguageExtensions.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=299481&r1=299480&r2=299481&view=diff == --- cfe/trunk/docs/LanguageExtensions.rst (original) +++ cfe/trunk/docs/LanguageExtensions.rst Tue Apr 4 17:45:20 2017 @@ -2342,6 +2342,6 @@ statements in C) } -The pragma can also be used with 'off' which turns FP contraction off for a +The pragma can also be used with ``off`` which turns FP contraction off for a section of the code. This can be useful when fast contraction is otherwise enabled for the translation unit with the ``-ffp-contract=fast` flag. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30009: Add support for '#pragma clang attribute'
aaron.ballman added a comment. Thank you for the update! I think this is getting close, though I have a few more comments inline. Comment at: docs/LanguageExtensions.rst:2338 +The attributes can also be written using the C++11 style syntax, as long +as only one attribute is specified in the square brackets: + Do we want to have the same restriction for GNU and declspec attributes, that only a single one can appear? If so, we should mention it more generally. Comment at: docs/LanguageExtensions.rst:2420 +- ``variable``: Can be used to apply attributes to variables, including + local variables, parameters, and global variables. + Are member variables included in this list? Perhaps this should also mention that it does not apply to Objective-C ivars. Comment at: include/clang/Basic/AttrSubjectMatchRules.h:17 +namespace clang { + +namespace attr { Can remove the newline. Comment at: include/clang/Basic/DiagnosticSemaKinds.td:765 + "'#pragma clang attribute push' regions ends here">; +def warn_pragm_attribute_no_pop_eof : Warning<"unterminated " + "'#pragma clang attribute push' at end of file">, Typo: pragm Is there value in this being in its own warning group from pragma-attribute-unused? It might make sense to disable any pragma attribute warning under the same group name, but I don't feel super strongly about it. Comment at: include/clang/Sema/Sema.h:8160 + /// '\#pragma clang attribute push' directives to the given declaration. + void AddPragmaAttributes(Scope *S, Decl *D); + arphaman wrote: > aaron.ballman wrote: > > I worry about new calls to ProcessDeclAttributes() that don't have a nearby > > call to AddPragmaAttributes(). I wonder if there's a way that we can combat > > that likely misuse? > Perhaps we could just always call `AddPragmaAttributes` from > `ProcessDeclAttributes` (after the declarator attributes are applied). That > would mean that `#pragma clang attribute` will apply its attributes earlier > than other pragmas or implicit attributes. I was wondering whether that would be a reasonable approach. I *think* it seems reasonable, however. Comment at: include/clang/Sema/Sema.h:8160 + /// '\#pragma clang attribute push' directives to the given declaration. + void AddPragmaAttributes(Scope *S, Decl *D); + aaron.ballman wrote: > arphaman wrote: > > aaron.ballman wrote: > > > I worry about new calls to ProcessDeclAttributes() that don't have a > > > nearby call to AddPragmaAttributes(). I wonder if there's a way that we > > > can combat that likely misuse? > > Perhaps we could just always call `AddPragmaAttributes` from > > `ProcessDeclAttributes` (after the declarator attributes are applied). That > > would mean that `#pragma clang attribute` will apply its attributes earlier > > than other pragmas or implicit attributes. > I was wondering whether that would be a reasonable approach. I *think* it > seems reasonable, however. Phab won't let me edit my comment for some reason, so replying a second time. I don't think it's a problem for the attributes to be added earlier because attributes are essentially an unordered list on the declarations anyways. If this really is a problem, I would hope that there's a test that will suddenly start failing for us. Comment at: lib/Sema/SemaAttr.cpp:631 +ProcessDeclAttributeList(S, D, Entry.Attribute); +HasFailed = Trap.hasErrorOccurred(); + } arphaman wrote: > aaron.ballman wrote: > > Do we only care about errors, or should we also care about warnings? > > Incorrect attributes that do not affect code generation often are treated > > as warnings (and the attribute is simply ignored) rather than errors, so > > the user may want to know about those issues. > I think it's important to try and get the warnings right as well. I think it > would make sense to emit the warnings for each declaration that receives the > attribute (including the first one). One issue that I found was that warnings > didn't tell the user which declaration was receiving the attribute. The > updated patch fixes that by ensuring that warnings are emitted for all > receivers and that each warning has an additional note that points to the > declaration that receives the attribute. > > This made me also rethink the SFINAE trap completely. I decided to avoid it. > Originally I thought that it would be nice to have it so that we can avoid > duplicate attribute-related errors when applying an attribute to each > declaration. There were a couple of issues with that approach: > - Attributes have receiver dependent errors/warnings that should be reported > for each declaration. Previously the patch was inconsistent for such errors; > it stopped applying the attribute only when the first d
[PATCH] D30009: Add support for '#pragma clang attribute'
aaron.ballman added a reviewer: rsmith. aaron.ballman added a comment. Adding Richard, since this is a fairly extensive change to the frontend and he may have some opinions as well. Repository: rL LLVM https://reviews.llvm.org/D30009 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r299488 - Another attempt to fix the sphinx warning from r299470
Author: anemet Date: Tue Apr 4 18:46:34 2017 New Revision: 299488 URL: http://llvm.org/viewvc/llvm-project?rev=299488&view=rev Log: Another attempt to fix the sphinx warning from r299470 Modified: cfe/trunk/docs/LanguageExtensions.rst Modified: cfe/trunk/docs/LanguageExtensions.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=299488&r1=299487&r2=299488&view=diff == --- cfe/trunk/docs/LanguageExtensions.rst (original) +++ cfe/trunk/docs/LanguageExtensions.rst Tue Apr 4 18:46:34 2017 @@ -2344,4 +2344,4 @@ statements in C) The pragma can also be used with ``off`` which turns FP contraction off for a section of the code. This can be useful when fast contraction is otherwise -enabled for the translation unit with the ``-ffp-contract=fast` flag. +enabled for the translation unit with the ``-ffp-contract=fast`` flag. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31633: test for thinlto handling of internal linkage
inglorion abandoned this revision. inglorion added a comment. We will not be needing this. https://reviews.llvm.org/D31633 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31692: [coroutines] Wrap the body of the coroutine in try-catch
GorNishanov created this revision. If unhandled_exception member function is present in the coroutine promise, wrap the body of the coroutine in: try { body } catch(...) { promise.unhandled_exception(); } https://reviews.llvm.org/D31692 Files: include/clang/AST/StmtCXX.h include/clang/Basic/DiagnosticSemaKinds.td lib/AST/StmtCXX.cpp lib/CodeGen/CGCoroutine.cpp lib/Sema/SemaCoroutine.cpp test/CodeGenCoroutines/coro-cleanup.cpp test/SemaCXX/coroutine-seh.cpp Index: test/SemaCXX/coroutine-seh.cpp === --- /dev/null +++ test/SemaCXX/coroutine-seh.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -std=c++1z -fcoroutines-ts -verify %s -fcxx-exceptions -fexceptions -triple x86_64-windows-msvc -fms-extensions +namespace std::experimental { +template struct coroutine_traits; + +template struct coroutine_handle { + coroutine_handle() = default; + static coroutine_handle from_address(void *) noexcept; +}; +template <> struct coroutine_handle { + static coroutine_handle from_address(void *) noexcept; + coroutine_handle() = default; + template + coroutine_handle(coroutine_handle) noexcept; +}; +} + +struct suspend_always { + bool await_ready() noexcept; + void await_suspend(std::experimental::coroutine_handle<>) noexcept; + void await_resume() noexcept; +}; + +template <> struct std::experimental::coroutine_traits { + struct promise_type { +void get_return_object() noexcept; +suspend_always initial_suspend() noexcept; +suspend_always final_suspend() noexcept; +void return_void() noexcept; +void unhandled_exception() noexcept; + }; +}; + +void SEH_used() { + __try { // expected-error {{cannot use SEH '__try' in a coroutine when C++ exceptions are enabled}} +co_return; // expected-note {{function is a coroutine due to use of 'co_return' here}} + } __except(0) {} +} Index: test/CodeGenCoroutines/coro-cleanup.cpp === --- test/CodeGenCoroutines/coro-cleanup.cpp +++ test/CodeGenCoroutines/coro-cleanup.cpp @@ -6,38 +6,38 @@ template struct coroutine_handle { coroutine_handle() = default; - static coroutine_handle from_address(void *) { return {}; } + static coroutine_handle from_address(void *) noexcept; }; template <> struct coroutine_handle { - static coroutine_handle from_address(void *) { return {}; } + static coroutine_handle from_address(void *) noexcept; coroutine_handle() = default; template - coroutine_handle(coroutine_handle) {} + coroutine_handle(coroutine_handle) noexcept; }; } struct suspend_always { - bool await_ready(); - void await_suspend(std::experimental::coroutine_handle<>); - void await_resume(); + bool await_ready() noexcept; + void await_suspend(std::experimental::coroutine_handle<>) noexcept; + void await_resume() noexcept; }; template <> struct std::experimental::coroutine_traits { struct promise_type { -void get_return_object(); -suspend_always initial_suspend(); -suspend_always final_suspend(); -void return_void(); +void get_return_object() noexcept; +suspend_always initial_suspend() noexcept; +suspend_always final_suspend() noexcept; +void return_void() noexcept; promise_type(); ~promise_type(); -void unhandled_exception(); +void unhandled_exception() noexcept; }; }; struct Cleanup { ~Cleanup(); }; void may_throw(); -// CHECK: define void @_Z1fv( +// CHECK-LABEL: define void @_Z1fv( void f() { // CHECK: call i8* @_Znwm(i64 @@ -52,23 +52,46 @@ // if may_throw throws, check that we destroy the promise and free the memory. // CHECK: invoke void @_Z9may_throwv( - // CHECK-NEXT: to label %{{.+}} unwind label %[[PromDtorPad:.+]] + // CHECK-NEXT: to label %{{.+}} unwind label %[[CatchPad:.+]] // CHECK: [[DeallocPad]]: // CHECK-NEXT: landingpad // CHECK-NEXT: cleanup // CHECK: br label %[[Dealloc:.+]] - // CHECK: [[PromDtorPad]]: - // CHECK-NEXT: landingpad - // CHECK-NEXT: cleanup - // CHECK: call void @_ZN7CleanupD1Ev(%struct.Cleanup* + // CHECK: [[CatchPad]]: + // CHECK-NEXT: landingpad + // CHECK-NEXT: catch i8* null + // CHECK: call void @_ZN7CleanupD1Ev( + // CHECK: br label %[[Catch:.+]] + + // CHECK: [[Catch]]: + // CHECK:call i8* @__cxa_begin_catch( + // CHECK:call void @_ZNSt12experimental16coroutine_traitsIJvEE12promise_type19unhandled_exceptionEv( + // CHECK:invoke void @__cxa_end_catch() + // CHECK-NEXT:to label %[[Cont:.+]] unwind + + // CHECK: [[Cont]]: + // CHECK-NEXT: br label %[[Cont2:.+]] + // CHECK: [[Cont2]]: + // CHECK-NEXT: br label %[[Cleanup:.+]] + + // CHECK: [[Cleanup]]: // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJvEE12promise_typeD1Ev( - // CHECK: br label %[[Dealloc]] + // CHECK: %[[Mem0:.+]] = call i8* @llvm.coro.free( + // CHECK: call void @_ZdlPv(i8* %[[Mem0]] // CHECK: [[Dealloc]]:
Buildbot numbers for the week of 03/19/2017 - 03/25/2017
Hello everyone, Below are some buildbot numbers for the week of 03/19/2017 - 03/25/2017. Please see the same data in attached csv files: The longest time each builder was red during the last week; "Status change ratio" by active builder (percent of builds that changed the builder status from greed to red or from red to green); Count of commits by project; Number of completed builds, failed builds and average build time for successful builds per active builder; Average waiting time for a revision to get build result per active builder (response time). Thanks Galina The longest time each builder was red during the last week: buildername | was_red +-- llvm-mips-linux| 105:31:31 clang-x64-ninja-win7 | 104:26:28 sanitizer-x86_64-linux | 59:47:58 perf-x86_64-penryn-O3-polly-before-vectorizer | 37:40:55 perf-x86_64-penryn-O3 | 36:15:51 perf-x86_64-penryn-O3-polly| 35:27:23 lldb-x86_64-darwin-13.4| 34:48:49 lldb-windows7-android | 33:35:16 perf-x86_64-penryn-O3-polly-parallel-fast | 32:22:37 perf-x86_64-penryn-O3-polly-before-vectorizer-unprofitable | 32:14:05 perf-x86_64-penryn-O3-polly-unprofitable | 32:11:27 perf-x86_64-penryn-O3-polly-before-vectorizer-detect-only | 32:06:05 perf-x86_64-penryn-O3-polly-fast | 30:52:22 llvm-clang-x86_64-expensive-checks-win | 26:47:11 sanitizer-x86_64-linux-bootstrap | 26:34:12 sanitizer-x86_64-linux-fast| 25:48:31 clang-cmake-aarch64-42vma | 23:43:15 clang-ppc64be-linux-multistage | 21:54:23 libomp-clang-ppc64le-linux-debian | 21:09:45 sanitizer-x86_64-linux-autoconf| 20:56:06 libcxx-libcxxabi-libunwind-aarch64-linux-noexceptions | 19:41:40 sanitizer-windows | 19:01:10 lldb-x86_64-ubuntu-14.04-android | 16:27:25 clang-ppc64be-linux| 15:08:36 lldb-x86_64-ubuntu-14.04-cmake | 13:42:59 clang-x86-windows-msvc2015 | 12:07:18 clang-cmake-armv7-a15-selfhost | 08:10:38 llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast | 07:46:58 clang-cmake-mipsel | 07:06:59 clang-cmake-aarch64-39vma | 06:56:58 clang-bpf-build| 06:47:38 clang-ppc64le-linux-lnt| 06:37:27 clang-ppc64le-linux| 06:37:12 clang-with-lto-ubuntu | 06:26:46 clang-cmake-aarch64-full | 06:25:58 clang-with-thin-lto-ubuntu | 06:16:42 clang-cmake-thumbv7-a15-full-sh| 06:03:47 clang-ppc64le-linux-multistage | 05:55:00 sanitizer-ppc64be-linux| 05:48:16 clang-cmake-mips | 05:27:49 clang-lld-x86_64-2stage| 05:17:40 clang-native-arm-lnt | 05:09:23 clang-cuda-build | 05:06:13 clang-ppc64be-linux-lnt| 05:05:36 clang-cmake-aarch64-quick | 05:01:18 clang-x86_64-linux-selfhost-modules| 04:48:43 clang-x86_64-linux-selfhost-modules-2 | 04:48:27 clang-s390x-linux | 04:44:51 clang-x86_64-debian-fast | 04:43:01 clang-atom-d525-fedora-rel | 04:39:48 sanitizer-ppc64le-linux| 04:21:51 clang-cmake-armv7-a15-selfhost-neon| 04:11:25 llvm-clang-lld-x86_64-scei-ps4-ubuntu-fast | 04:10:01 lld-x86_64-darwin13| 04:06:04 lldb-amd64-ninja-freebsd11 | 04:00:30 clang-cmake-thumbv7-a15| 03:53:09 lld-x86_64-win7| 03:51:56 lld-x86_64-freebsd | 03:47:38 libcxx-libcxxabi-x86_64-linux-ubuntu-cxx03 | 03:39:31 libcxx-libcxxabi-x86_64-l
Buildbot numbers for the week of 03/26/2017 - 04/01/2017
Hello everyone, Below are some buildbot numbers for the last week of 03/26/2017 - 04/01/2017. Please see the same data in attached csv files: The longest time each builder was red during the last week; "Status change ratio" by active builder (percent of builds that changed the builder status from greed to red or from red to green); Count of commits by project; Number of completed builds, failed builds and average build time for successful builds per active builder; Average waiting time for a revision to get build result per active builder (response time). Thanks Galina The longest time each builder was red during the last week: buildername | was_red +- lldb-x86_64-ubuntu-14.04-android | 53:25:17 clang-cmake-aarch64-42vma | 47:17:29 clang-cmake-armv7-a15-selfhost | 44:15:27 clang-cmake-aarch64-39vma | 43:35:45 clang-cmake-thumbv7-a15| 43:19:37 clang-cmake-aarch64-full | 41:11:35 clang-cmake-armv7-a15-selfhost-neon| 40:45:13 clang-cmake-thumbv7-a15-full-sh| 40:09:12 clang-cmake-armv7-a15-full | 39:51:55 clang-cmake-aarch64-quick | 39:31:18 clang-cmake-armv7-a15 | 39:19:48 clang-x64-ninja-win7 | 36:13:50 sanitizer-x86_64-linux-fast| 26:53:39 sanitizer-x86_64-linux-bootstrap | 26:10:21 clang-cuda-build | 24:32:38 clang-cmake-mipsel | 20:19:11 clang-x86_64-linux-selfhost-modules-2 | 15:05:11 llvm-clang-x86_64-expensive-checks-win | 14:57:08 clang-with-lto-ubuntu | 12:32:11 clang-with-thin-lto-ubuntu | 12:29:37 lld-x86_64-darwin13| 11:36:02 lld-x86_64-win7| 11:35:21 lld-x86_64-freebsd | 11:27:10 libcxx-libcxxabi-libunwind-aarch64-linux | 08:10:46 sanitizer-x86_64-linux | 07:05:55 clang-ppc64le-linux-multistage | 04:41:01 clang-cmake-mips | 04:20:59 lldb-x86-windows-msvc2015 | 03:44:31 llvm-sphinx-docs | 03:07:06 llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast | 02:54:24 clang-x86-windows-msvc2015 | 02:47:52 lldb-windows7-android | 02:40:12 libcxx-libcxxabi-libunwind-x86_64-linux-ubuntu | 02:26:57 sanitizer-x86_64-linux-fuzzer | 02:18:55 libcxx-libcxxabi-x86_64-linux-ubuntu-msan | 02:18:08 clang-ppc64be-linux-lnt| 02:14:36 clang-bpf-build| 02:13:39 libcxx-libcxxabi-x86_64-linux-ubuntu-tsan | 02:11:48 sanitizer-windows | 02:11:05 clang-ppc64be-linux| 02:07:46 sanitizer-ppc64le-linux| 02:07:06 libcxx-libcxxabi-libunwind-arm-linux | 01:57:55 clang-ppc64be-linux-multistage | 01:56:11 clang-ppc64le-linux-lnt| 01:55:49 libcxx-libcxxabi-x86_64-linux-ubuntu-asan | 01:38:57 libcxx-libcxxabi-singlethreaded-x86_64-linux-debian| 01:35:16 libcxx-libcxxabi-x86_64-linux-debian-noexceptions | 01:32:15 clang-ppc64le-linux| 01:25:42 libcxx-libcxxabi-libunwind-aarch64-linux-noexceptions | 01:23:46 libcxx-libcxxabi-x86_64-linux-debian | 01:22:18 libcxx-libcxxabi-x86_64-linux-ubuntu-ubsan | 01:19:22 lldb-x86_64-darwin-13.4| 01:19:06 libcxx-libcxxabi-x86_64-linux-ubuntu-cxx14 | 01:18:04 lldb-x86_64-ubuntu-14.04-buildserver | 01:16:23 libcxx-libcxxabi-libunwind-arm-linux-noexceptions | 01:13:52 libcxx-libcxxabi-x86_64-linux-ubuntu-cxx11 | 01:11:09 clang-x86_64-debian-fast | 01:01:47 libcxx-libcxxabi-x86_64-linux-ubuntu-gcc49-cxx11 | 01:01:39 clang-tools-sphinx-docs| 01:00:40 libcxx-libcxxabi-x86_64-
[PATCH] D27565: [libcxx] Fix __compressed_pair so it doesn't copy the argument multiple times, and add constexpr.
K-ballo added a comment. I don't see any potential layout change, other than the case in which both `T1` and `T2` are empty (which I understand doesn't happen within libc++). As far as I know, the rest of the cases should result in the same layout regardless of whether EBO actually applies or not. Some notes inline. Comment at: include/memory:2058 -template ::type, - typename remove_cv<_T2>::type>::value, -bool = is_empty<_T1>::value - && !__libcpp_is_final<_T1>::value, -bool = is_empty<_T2>::value - && !__libcpp_is_final<_T2>::value - > -struct __libcpp_compressed_pair_switch; - -template -struct __libcpp_compressed_pair_switch<_T1, _T2, IsSame, false, false> {enum {value = 0};}; - -template -struct __libcpp_compressed_pair_switch<_T1, _T2, IsSame, true, false> {enum {value = 1};}; - -template -struct __libcpp_compressed_pair_switch<_T1, _T2, IsSame, false, true> {enum {value = 2};}; - -template -struct __libcpp_compressed_pair_switch<_T1, _T2, false, true, true>{enum {value = 3};}; - -template -struct __libcpp_compressed_pair_switch<_T1, _T2, true, true, true> {enum {value = 1};}; - -template ::value> -class __libcpp_compressed_pair_imp; +template ::value + && !__libcpp_is_final<_Tp>::value> Should be `_IsEmpty` Comment at: include/memory:2063 + typedef typename remove_reference<_Tp>::type& reference; + typedef const typename remove_reference<_Tp>::type& const_reference; If `_Tp` can actually be a reference type, turning it into reference to const here doesn't seem right Comment at: include/memory:2110 + _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(_Up&& __u) + : __value_(_VSTD::forward<_Up>(__u)) {}; This use of `__value_` as a type is overly smart, consider just using `_Tp` for clarity https://reviews.llvm.org/D27565 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31696: Automatically add include-what-you-use for when building in tree
zturner created this revision. Herald added subscribers: mgorny, rengolin, aemerson. It's a little bit annoying to have to manually edit files and then deal with git thinking that you've got untracked files, and thusly deleting them when you run `git clean -fd`. Although this is not an officially sanctioned LLVM tool, there seems to be little harm in having this logic here and it makes life easier for anyone who wants to use this. https://reviews.llvm.org/D31696 Files: clang/tools/.gitignore clang/tools/CMakeLists.txt Index: clang/tools/CMakeLists.txt === --- clang/tools/CMakeLists.txt +++ clang/tools/CMakeLists.txt @@ -30,3 +30,8 @@ # libclang may require clang-tidy in clang-tools-extra. add_clang_subdirectory(libclang) + +# if include-what-you-use is cloned for building in-tree, add it here. +if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/include-what-you-use") + add_clang_subdirectory(include-what-you-use) +endif() Index: clang/tools/.gitignore === --- /dev/null +++ clang/tools/.gitignore @@ -0,0 +1,13 @@ +#==# +# This file specifies intentionally untracked files that git should ignore. +# See: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html +# +# This file is intentionally different from the output of `git svn show-ignore`, +# as most of those are useless. +#==# + +#==# +# File extensions to be ignored anywhere in the tree. +#==# +# The include-what-you-use project, for when building in-tree. +include-what-you-use Index: clang/tools/CMakeLists.txt === --- clang/tools/CMakeLists.txt +++ clang/tools/CMakeLists.txt @@ -30,3 +30,8 @@ # libclang may require clang-tidy in clang-tools-extra. add_clang_subdirectory(libclang) + +# if include-what-you-use is cloned for building in-tree, add it here. +if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/include-what-you-use") + add_clang_subdirectory(include-what-you-use) +endif() Index: clang/tools/.gitignore === --- /dev/null +++ clang/tools/.gitignore @@ -0,0 +1,13 @@ +#==# +# This file specifies intentionally untracked files that git should ignore. +# See: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html +# +# This file is intentionally different from the output of `git svn show-ignore`, +# as most of those are useless. +#==# + +#==# +# File extensions to be ignored anywhere in the tree. +#==# +# The include-what-you-use project, for when building in-tree. +include-what-you-use ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31697: Check for null before using TUScope
zturner created this revision. To be honest I don't really understand anything about this code. I encountered a situation when running `include-what-you-use` against LLVM where `TUScope` was null here, triggering a segfault. Some surrounding comments and code suggests that this variable is specific to Objective C, but I don't really grok whether null is indicative here of an earlier problem or whether it should actually be handled. There are other places in this file where it is checked for null, so there is at least some precedent for it in Sema. https://reviews.llvm.org/D31697 Files: clang/lib/Sema/SemaDecl.cpp Index: clang/lib/Sema/SemaDecl.cpp === --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -1906,7 +1906,8 @@ // entirely, but we're not there yet. DeclContext *SavedContext = CurContext; CurContext = Parent; - PushOnScopeChains(New, TUScope); + if (TUScope) +PushOnScopeChains(New, TUScope); CurContext = SavedContext; return New; } Index: clang/lib/Sema/SemaDecl.cpp === --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -1906,7 +1906,8 @@ // entirely, but we're not there yet. DeclContext *SavedContext = CurContext; CurContext = Parent; - PushOnScopeChains(New, TUScope); + if (TUScope) +PushOnScopeChains(New, TUScope); CurContext = SavedContext; return New; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D31698: clang-format: [JS] fix whitespace around "of" operator.
mprobst created this revision. Herald added a subscriber: klimek. Previously: import {of } from 'x'; of (null); Now: import {of} from 'x'; of(null); https://reviews.llvm.org/D31698 Files: lib/Format/TokenAnnotator.cpp unittests/Format/FormatTestJS.cpp Index: unittests/Format/FormatTestJS.cpp === --- unittests/Format/FormatTestJS.cpp +++ unittests/Format/FormatTestJS.cpp @@ -132,6 +132,8 @@ verifyFormat("x.interface = 1;"); verifyFormat("x.for = 1;"); verifyFormat("x.of() = 1;"); + verifyFormat("of(null);"); + verifyFormat("import {of} from 'x';"); verifyFormat("x.in() = 1;"); verifyFormat("x.let() = 1;"); verifyFormat("x.var() = 1;"); Index: lib/Format/TokenAnnotator.cpp === --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -2270,8 +2270,11 @@ if (Right.is(tok::l_paren) && Line.MustBeDeclaration && Left.Tok.getIdentifierInfo()) return false; -if (Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in, - Keywords.kw_of, tok::kw_const) && +if ((Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in, + tok::kw_const) || + // "of" can only occur in a for loop, as a "const x of y". + (Left.is(Keywords.kw_of) && Left.Previous && + Left.Previous->Tok.getIdentifierInfo())) && (!Left.Previous || !Left.Previous->is(tok::period))) return true; if (Left.isOneOf(tok::kw_for, Keywords.kw_as) && Left.Previous && Index: unittests/Format/FormatTestJS.cpp === --- unittests/Format/FormatTestJS.cpp +++ unittests/Format/FormatTestJS.cpp @@ -132,6 +132,8 @@ verifyFormat("x.interface = 1;"); verifyFormat("x.for = 1;"); verifyFormat("x.of() = 1;"); + verifyFormat("of(null);"); + verifyFormat("import {of} from 'x';"); verifyFormat("x.in() = 1;"); verifyFormat("x.let() = 1;"); verifyFormat("x.var() = 1;"); Index: lib/Format/TokenAnnotator.cpp === --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -2270,8 +2270,11 @@ if (Right.is(tok::l_paren) && Line.MustBeDeclaration && Left.Tok.getIdentifierInfo()) return false; -if (Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in, - Keywords.kw_of, tok::kw_const) && +if ((Left.isOneOf(Keywords.kw_let, Keywords.kw_var, Keywords.kw_in, + tok::kw_const) || + // "of" can only occur in a for loop, as a "const x of y". + (Left.is(Keywords.kw_of) && Left.Previous && + Left.Previous->Tok.getIdentifierInfo())) && (!Left.Previous || !Left.Previous->is(tok::period))) return true; if (Left.isOneOf(tok::kw_for, Keywords.kw_as) && Left.Previous && ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D25444: [coroutines] Add coro.end handling
GorNishanov updated this revision to Diff 94161. GorNishanov retitled this revision from "[coroutines] Hybrid (bundle + bool returning coro.end approach)" to "[coroutines] Add coro.end handling". GorNishanov edited the summary of this revision. GorNishanov added a subscriber: cfe-commits. GorNishanov added a comment. Herald added a subscriber: EricWF. Preparing to land https://reviews.llvm.org/D25444 Files: lib/CodeGen/CGCoroutine.cpp test/CodeGenCoroutines/coro-eh-cleanup.cpp Index: test/CodeGenCoroutines/coro-eh-cleanup.cpp === --- /dev/null +++ test/CodeGenCoroutines/coro-eh-cleanup.cpp @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -std=c++1z -fcoroutines-ts -triple=x86_64-pc-windows-msvc18.0.0 -emit-llvm %s -o - -fexceptions -fcxx-exceptions -disable-llvm-passes | FileCheck %s +// RUN: %clang_cc1 -std=c++1z -fcoroutines-ts -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s -fexceptions -fcxx-exceptions -disable-llvm-passes | FileCheck --check-prefix=CHECK-LPAD %s + +namespace std::experimental { +template struct coroutine_traits { + using promise_type = typename R::promise_type; +}; + +template struct coroutine_handle; + +template <> struct coroutine_handle { + static coroutine_handle from_address(void *) noexcept; + coroutine_handle() = default; + template + coroutine_handle(coroutine_handle) noexcept; +}; +template struct coroutine_handle: coroutine_handle { + coroutine_handle() = default; + static coroutine_handle from_address(void *) noexcept; +}; +} + +struct suspend_always { + bool await_ready() noexcept; + void await_suspend(std::experimental::coroutine_handle<>) noexcept; + void await_resume() noexcept; +}; + +struct coro_t { + struct promise_type { +coro_t get_return_object() noexcept; +suspend_always initial_suspend() noexcept; +suspend_always final_suspend() noexcept; +void return_void() noexcept; +void unhandled_exception() noexcept; + }; +}; + +struct Cleanup { ~Cleanup(); }; +void may_throw(); + +coro_t f() { + Cleanup x; + may_throw(); + co_return; +} + +// CHECK: @"\01?f@@YA?AUcoro_t@@XZ"( +// CHECK: invoke void @"\01?may_throw@@YAXXZ"() +// CHECK: to label %[[CONT:.+]] unwind label %[[EHCLEANUP:.+]] +// CHECK: [[EHCLEANUP]]: +// CHECK: %[[INNERPAD:.+]] = cleanuppad within none [] +// CHECK: call void @"\01??_DCleanup@@QEAAXXZ"( +// CHECK: cleanupret from %[[INNERPAD]] unwind label %[[COROENDBB:.+]] +// CHECK: [[COROENDBB]]: +// CHECK-NEXT: %[[CLPAD:.+]] = cleanuppad within none +// CHECK-NEXT: call i1 @llvm.coro.end(i8* null, i1 true) [ "funclet"(token %[[CLPAD]]) ] +// CHECK-NEXT: cleanupret from %[[CLPAD]] unwind label + +// CHECK-LPAD: @_Z1fv( +// CHECK-LPAD: invoke void @_Z9may_throwv() +// CHECK-LPAD: to label %[[CONT:.+]] unwind label %[[EHCLEANUP:.+]] +// CHECK-LPAD: [[EHCLEANUP]]: +// CHECK-LPAD:landingpad { i8*, i32 } +// CHECK-LPAD: cleanup +// CHECK-LPAD: call void @_ZN7CleanupD1Ev( +// CHECK-LPAD: %[[I1RESUME:.+]] = call i1 @llvm.coro.end(i8* null, i1 true) +// CHECK-LPAD: br i1 %[[I1RESUME]], label %[[EHRESUME:.+]], label +// CHECK-LPAD: [[EHRESUME]]: +// CHECK-LPAD-NEXT: %[[exn:.+]] = load i8*, i8** %exn.slot, align 8 +// CHECK-LPAD-NEXT: %[[sel:.+]] = load i32, i32* %ehselector.slot, align 4 +// CHECK-LPAD-NEXT: %[[val1:.+]] = insertvalue { i8*, i32 } undef, i8* %[[exn]], 0 +// CHECK-LPAD-NEXT: %[[val2:.+]] = insertvalue { i8*, i32 } %[[val1]], i32 %[[sel]], 1 +// CHECK-LPAD-NEXT: resume { i8*, i32 } %[[val2]] Index: lib/CodeGen/CGCoroutine.cpp === --- lib/CodeGen/CGCoroutine.cpp +++ lib/CodeGen/CGCoroutine.cpp @@ -215,6 +215,43 @@ EmitBranchThroughCleanup(CurCoro.Data->FinalJD); } +// For WinEH exception representation backend need to know what funclet coro.end +// belongs to. That information is passed in a funclet bundle. +static SmallVector +getBundlesForCoroEnd(CodeGenFunction &CGF) { + SmallVector BundleList; + + if (llvm::Instruction *EHPad = CGF.CurrentFuncletPad) +BundleList.emplace_back("funclet", EHPad); + + return BundleList; +} + +namespace { +// We will insert coro.end to cut any of the destructors for objects that +// do not need to be destroyed once the coroutine is resumed. +// See llvm/docs/Coroutines.rst for more details about coro.end. +struct CallCoroEnd final : public EHScopeStack::Cleanup { + void Emit(CodeGenFunction &CGF, Flags flags) override { +auto &CGM = CGF.CGM; +auto *NullPtr = llvm::ConstantPointerNull::get(CGF.Int8PtrTy); +llvm::Function *CoroEndFn = CGM.getIntrinsic(llvm::Intrinsic::coro_end); +// See if we have a funclet bundle to associate coro.end with. (WinEH) +auto Bundles = getBundlesForCoroEnd(CGF); +auto *CoroEnd = CGF.Builder.CreateCall( +CoroEndFn, {NullPtr, CGF.Builder.getTrue()}, Bundles); +if (Bundles.empty()) { + // Otherwise, (landingpad model), create a co
r299510 - [coroutines] Add coro.end handling
Author: gornishanov Date: Tue Apr 4 23:55:03 2017 New Revision: 299510 URL: http://llvm.org/viewvc/llvm-project?rev=299510&view=rev Log: [coroutines] Add coro.end handling Summary: For WinEH, We add a funclet bundle to a coro.end call, so that CoroSplit in LLVM can replace it with cleanup ret and cut the rest out. For landing pad, we add a branch to resume block if coro.end returns true. LLVM Part: https://reviews.llvm.org/D25445 Reviewers: majnemer Reviewed By: majnemer Subscribers: EricWF, cfe-commits, rsmith, mehdi_amini Differential Revision: https://reviews.llvm.org/D25444 Added: cfe/trunk/test/CodeGenCoroutines/coro-eh-cleanup.cpp Modified: cfe/trunk/lib/CodeGen/CGCoroutine.cpp Modified: cfe/trunk/lib/CodeGen/CGCoroutine.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCoroutine.cpp?rev=299510&r1=299509&r2=299510&view=diff == --- cfe/trunk/lib/CodeGen/CGCoroutine.cpp (original) +++ cfe/trunk/lib/CodeGen/CGCoroutine.cpp Tue Apr 4 23:55:03 2017 @@ -215,6 +215,43 @@ void CodeGenFunction::EmitCoreturnStmt(C EmitBranchThroughCleanup(CurCoro.Data->FinalJD); } +// For WinEH exception representation backend need to know what funclet coro.end +// belongs to. That information is passed in a funclet bundle. +static SmallVector +getBundlesForCoroEnd(CodeGenFunction &CGF) { + SmallVector BundleList; + + if (llvm::Instruction *EHPad = CGF.CurrentFuncletPad) +BundleList.emplace_back("funclet", EHPad); + + return BundleList; +} + +namespace { +// We will insert coro.end to cut any of the destructors for objects that +// do not need to be destroyed once the coroutine is resumed. +// See llvm/docs/Coroutines.rst for more details about coro.end. +struct CallCoroEnd final : public EHScopeStack::Cleanup { + void Emit(CodeGenFunction &CGF, Flags flags) override { +auto &CGM = CGF.CGM; +auto *NullPtr = llvm::ConstantPointerNull::get(CGF.Int8PtrTy); +llvm::Function *CoroEndFn = CGM.getIntrinsic(llvm::Intrinsic::coro_end); +// See if we have a funclet bundle to associate coro.end with. (WinEH) +auto Bundles = getBundlesForCoroEnd(CGF); +auto *CoroEnd = CGF.Builder.CreateCall( +CoroEndFn, {NullPtr, CGF.Builder.getTrue()}, Bundles); +if (Bundles.empty()) { + // Otherwise, (landingpad model), create a conditional branch that leads + // either to a cleanup block or a block with EH resume instruction. + auto *ResumeBB = CGF.getEHResumeBlock(/*cleanup=*/true); + auto *CleanupContBB = CGF.createBasicBlock("cleanup.cont"); + CGF.Builder.CreateCondBr(CoroEnd, ResumeBB, CleanupContBB); + CGF.EmitBlock(CleanupContBB); +} + } +}; +} + namespace { // Make sure to call coro.delete on scope exit. struct CallCoroDelete final : public EHScopeStack::Cleanup { @@ -273,6 +310,8 @@ void CodeGenFunction::EmitCoroutineBody( EmitStmt(S.getPromiseDeclStmt()); +EHStack.pushCleanup(EHCleanup); + CurCoro.Data->FinalJD = getJumpDestInCurrentScope(FinalBB); // FIXME: Emit initial suspend and more before the body. @@ -290,6 +329,8 @@ void CodeGenFunction::EmitCoroutineBody( } EmitBlock(RetBB); + llvm::Function *CoroEnd = CGM.getIntrinsic(llvm::Intrinsic::coro_end); + Builder.CreateCall(CoroEnd, {NullPtr, Builder.getFalse()}); // FIXME: Emit return for the coroutine return object. } Added: cfe/trunk/test/CodeGenCoroutines/coro-eh-cleanup.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCoroutines/coro-eh-cleanup.cpp?rev=299510&view=auto == --- cfe/trunk/test/CodeGenCoroutines/coro-eh-cleanup.cpp (added) +++ cfe/trunk/test/CodeGenCoroutines/coro-eh-cleanup.cpp Tue Apr 4 23:55:03 2017 @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -std=c++1z -fcoroutines-ts -triple=x86_64-pc-windows-msvc18.0.0 -emit-llvm %s -o - -fexceptions -fcxx-exceptions -disable-llvm-passes | FileCheck %s +// RUN: %clang_cc1 -std=c++1z -fcoroutines-ts -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s -fexceptions -fcxx-exceptions -disable-llvm-passes | FileCheck --check-prefix=CHECK-LPAD %s + +namespace std::experimental { +template struct coroutine_traits { + using promise_type = typename R::promise_type; +}; + +template struct coroutine_handle; + +template <> struct coroutine_handle { + static coroutine_handle from_address(void *) noexcept; + coroutine_handle() = default; + template + coroutine_handle(coroutine_handle) noexcept; +}; +template struct coroutine_handle: coroutine_handle { + coroutine_handle() = default; + static coroutine_handle from_address(void *) noexcept; +}; +} + +struct suspend_always { + bool await_ready() noexcept; + void await_suspend(std::experimental::coroutine_handle<>) noexcept; + void await_resume() noexcept; +}; + +struct coro_t { + struct promise_type { +coro_t get_return_object() noexcept; +suspen
[PATCH] D25444: [coroutines] Add coro.end handling
This revision was automatically updated to reflect the committed changes. Closed by commit rL299510: [coroutines] Add coro.end handling (authored by GorNishanov). Changed prior to commit: https://reviews.llvm.org/D25444?vs=94161&id=94162#toc Repository: rL LLVM https://reviews.llvm.org/D25444 Files: cfe/trunk/lib/CodeGen/CGCoroutine.cpp cfe/trunk/test/CodeGenCoroutines/coro-eh-cleanup.cpp Index: cfe/trunk/lib/CodeGen/CGCoroutine.cpp === --- cfe/trunk/lib/CodeGen/CGCoroutine.cpp +++ cfe/trunk/lib/CodeGen/CGCoroutine.cpp @@ -215,6 +215,43 @@ EmitBranchThroughCleanup(CurCoro.Data->FinalJD); } +// For WinEH exception representation backend need to know what funclet coro.end +// belongs to. That information is passed in a funclet bundle. +static SmallVector +getBundlesForCoroEnd(CodeGenFunction &CGF) { + SmallVector BundleList; + + if (llvm::Instruction *EHPad = CGF.CurrentFuncletPad) +BundleList.emplace_back("funclet", EHPad); + + return BundleList; +} + +namespace { +// We will insert coro.end to cut any of the destructors for objects that +// do not need to be destroyed once the coroutine is resumed. +// See llvm/docs/Coroutines.rst for more details about coro.end. +struct CallCoroEnd final : public EHScopeStack::Cleanup { + void Emit(CodeGenFunction &CGF, Flags flags) override { +auto &CGM = CGF.CGM; +auto *NullPtr = llvm::ConstantPointerNull::get(CGF.Int8PtrTy); +llvm::Function *CoroEndFn = CGM.getIntrinsic(llvm::Intrinsic::coro_end); +// See if we have a funclet bundle to associate coro.end with. (WinEH) +auto Bundles = getBundlesForCoroEnd(CGF); +auto *CoroEnd = CGF.Builder.CreateCall( +CoroEndFn, {NullPtr, CGF.Builder.getTrue()}, Bundles); +if (Bundles.empty()) { + // Otherwise, (landingpad model), create a conditional branch that leads + // either to a cleanup block or a block with EH resume instruction. + auto *ResumeBB = CGF.getEHResumeBlock(/*cleanup=*/true); + auto *CleanupContBB = CGF.createBasicBlock("cleanup.cont"); + CGF.Builder.CreateCondBr(CoroEnd, ResumeBB, CleanupContBB); + CGF.EmitBlock(CleanupContBB); +} + } +}; +} + namespace { // Make sure to call coro.delete on scope exit. struct CallCoroDelete final : public EHScopeStack::Cleanup { @@ -273,6 +310,8 @@ EmitStmt(S.getPromiseDeclStmt()); +EHStack.pushCleanup(EHCleanup); + CurCoro.Data->FinalJD = getJumpDestInCurrentScope(FinalBB); // FIXME: Emit initial suspend and more before the body. @@ -290,6 +329,8 @@ } EmitBlock(RetBB); + llvm::Function *CoroEnd = CGM.getIntrinsic(llvm::Intrinsic::coro_end); + Builder.CreateCall(CoroEnd, {NullPtr, Builder.getFalse()}); // FIXME: Emit return for the coroutine return object. } Index: cfe/trunk/test/CodeGenCoroutines/coro-eh-cleanup.cpp === --- cfe/trunk/test/CodeGenCoroutines/coro-eh-cleanup.cpp +++ cfe/trunk/test/CodeGenCoroutines/coro-eh-cleanup.cpp @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -std=c++1z -fcoroutines-ts -triple=x86_64-pc-windows-msvc18.0.0 -emit-llvm %s -o - -fexceptions -fcxx-exceptions -disable-llvm-passes | FileCheck %s +// RUN: %clang_cc1 -std=c++1z -fcoroutines-ts -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s -fexceptions -fcxx-exceptions -disable-llvm-passes | FileCheck --check-prefix=CHECK-LPAD %s + +namespace std::experimental { +template struct coroutine_traits { + using promise_type = typename R::promise_type; +}; + +template struct coroutine_handle; + +template <> struct coroutine_handle { + static coroutine_handle from_address(void *) noexcept; + coroutine_handle() = default; + template + coroutine_handle(coroutine_handle) noexcept; +}; +template struct coroutine_handle: coroutine_handle { + coroutine_handle() = default; + static coroutine_handle from_address(void *) noexcept; +}; +} + +struct suspend_always { + bool await_ready() noexcept; + void await_suspend(std::experimental::coroutine_handle<>) noexcept; + void await_resume() noexcept; +}; + +struct coro_t { + struct promise_type { +coro_t get_return_object() noexcept; +suspend_always initial_suspend() noexcept; +suspend_always final_suspend() noexcept; +void return_void() noexcept; +void unhandled_exception() noexcept; + }; +}; + +struct Cleanup { ~Cleanup(); }; +void may_throw(); + +coro_t f() { + Cleanup x; + may_throw(); + co_return; +} + +// CHECK: @"\01?f@@YA?AUcoro_t@@XZ"( +// CHECK: invoke void @"\01?may_throw@@YAXXZ"() +// CHECK: to label %[[CONT:.+]] unwind label %[[EHCLEANUP:.+]] +// CHECK: [[EHCLEANUP]]: +// CHECK: %[[INNERPAD:.+]] = cleanuppad within none [] +// CHECK: call void @"\01??_DCleanup@@QEAAXXZ"( +// CHECK: cleanupret from %[[INNERPAD]] unwind label %[[COROENDBB:.+]] +// CHECK: [[COROENDBB]]: +// CHECK-NEXT: %[[CLPAD:.+]] = cleanuppad within none +// CHECK-NEXT: call i1 @llvm.