r297129 - [analyzer] Fix crash when building CFG with variable of incomplete type
Author: mboehme Date: Tue Mar 7 02:42:37 2017 New Revision: 297129 URL: http://llvm.org/viewvc/llvm-project?rev=297129&view=rev Log: [analyzer] Fix crash when building CFG with variable of incomplete type Summary: I've included a unit test with a function template containing a variable of incomplete type. Clang compiles this without errors (the standard does not require a diagnostic in this case). Without the fix, this case triggers the crash. Reviewers: klimek Reviewed By: klimek Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D30636 Modified: cfe/trunk/lib/Analysis/CFG.cpp cfe/trunk/unittests/Analysis/CFGTest.cpp Modified: cfe/trunk/lib/Analysis/CFG.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=297129&r1=297128&r2=297129&view=diff == --- cfe/trunk/lib/Analysis/CFG.cpp (original) +++ cfe/trunk/lib/Analysis/CFG.cpp Tue Mar 7 02:42:37 2017 @@ -1390,7 +1390,7 @@ LocalScope* CFGBuilder::addLocalScopeFor // Check if type is a C++ class with non-trivial destructor. if (const CXXRecordDecl *CD = QT->getAsCXXRecordDecl()) -if (!CD->hasTrivialDestructor()) { +if (CD->hasDefinition() && !CD->hasTrivialDestructor()) { // Add the variable to scope Scope = createOrReuseLocalScope(Scope); Scope->addVar(VD); Modified: cfe/trunk/unittests/Analysis/CFGTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Analysis/CFGTest.cpp?rev=297129&r1=297128&r2=297129&view=diff == --- cfe/trunk/unittests/Analysis/CFGTest.cpp (original) +++ cfe/trunk/unittests/Analysis/CFGTest.cpp Tue Mar 7 02:42:37 2017 @@ -35,7 +35,9 @@ public: if (!Body) return; TheBuildResult = SawFunctionBody; -if (CFG::buildCFG(nullptr, Body, Result.Context, CFG::BuildOptions())) +CFG::BuildOptions Options; +Options.AddImplicitDtors = true; +if (CFG::buildCFG(nullptr, Body, Result.Context, Options)) TheBuildResult = BuiltCFG; } }; @@ -74,6 +76,16 @@ TEST(CFG, DeleteExpressionOnDependentTyp "}\n"; EXPECT_EQ(BuiltCFG, BuildCFG(Code)); } + +// Constructing a CFG on a function template with a variable of incomplete type +// should not crash. +TEST(CFG, VariableOfIncompleteType) { + const char *Code = "template void f() {\n" + " class Undefined;\n" + " Undefined u;\n" + "}\n"; + EXPECT_EQ(BuiltCFG, BuildCFG(Code)); +} } // namespace } // namespace analysis ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30636: [analyzer] Fix crash when building CFG with variable of incomplete type
This revision was automatically updated to reflect the committed changes. Closed by commit rL297129: [analyzer] Fix crash when building CFG with variable of incomplete type (authored by mboehme). Changed prior to commit: https://reviews.llvm.org/D30636?vs=90660&id=90810#toc Repository: rL LLVM https://reviews.llvm.org/D30636 Files: cfe/trunk/lib/Analysis/CFG.cpp cfe/trunk/unittests/Analysis/CFGTest.cpp Index: cfe/trunk/lib/Analysis/CFG.cpp === --- cfe/trunk/lib/Analysis/CFG.cpp +++ cfe/trunk/lib/Analysis/CFG.cpp @@ -1390,7 +1390,7 @@ // Check if type is a C++ class with non-trivial destructor. if (const CXXRecordDecl *CD = QT->getAsCXXRecordDecl()) -if (!CD->hasTrivialDestructor()) { +if (CD->hasDefinition() && !CD->hasTrivialDestructor()) { // Add the variable to scope Scope = createOrReuseLocalScope(Scope); Scope->addVar(VD); Index: cfe/trunk/unittests/Analysis/CFGTest.cpp === --- cfe/trunk/unittests/Analysis/CFGTest.cpp +++ cfe/trunk/unittests/Analysis/CFGTest.cpp @@ -35,7 +35,9 @@ if (!Body) return; TheBuildResult = SawFunctionBody; -if (CFG::buildCFG(nullptr, Body, Result.Context, CFG::BuildOptions())) +CFG::BuildOptions Options; +Options.AddImplicitDtors = true; +if (CFG::buildCFG(nullptr, Body, Result.Context, Options)) TheBuildResult = BuiltCFG; } }; @@ -75,6 +77,16 @@ EXPECT_EQ(BuiltCFG, BuildCFG(Code)); } +// Constructing a CFG on a function template with a variable of incomplete type +// should not crash. +TEST(CFG, VariableOfIncompleteType) { + const char *Code = "template void f() {\n" + " class Undefined;\n" + " Undefined u;\n" + "}\n"; + EXPECT_EQ(BuiltCFG, BuildCFG(Code)); +} + } // namespace } // namespace analysis } // namespace clang Index: cfe/trunk/lib/Analysis/CFG.cpp === --- cfe/trunk/lib/Analysis/CFG.cpp +++ cfe/trunk/lib/Analysis/CFG.cpp @@ -1390,7 +1390,7 @@ // Check if type is a C++ class with non-trivial destructor. if (const CXXRecordDecl *CD = QT->getAsCXXRecordDecl()) -if (!CD->hasTrivialDestructor()) { +if (CD->hasDefinition() && !CD->hasTrivialDestructor()) { // Add the variable to scope Scope = createOrReuseLocalScope(Scope); Scope->addVar(VD); Index: cfe/trunk/unittests/Analysis/CFGTest.cpp === --- cfe/trunk/unittests/Analysis/CFGTest.cpp +++ cfe/trunk/unittests/Analysis/CFGTest.cpp @@ -35,7 +35,9 @@ if (!Body) return; TheBuildResult = SawFunctionBody; -if (CFG::buildCFG(nullptr, Body, Result.Context, CFG::BuildOptions())) +CFG::BuildOptions Options; +Options.AddImplicitDtors = true; +if (CFG::buildCFG(nullptr, Body, Result.Context, Options)) TheBuildResult = BuiltCFG; } }; @@ -75,6 +77,16 @@ EXPECT_EQ(BuiltCFG, BuildCFG(Code)); } +// Constructing a CFG on a function template with a variable of incomplete type +// should not crash. +TEST(CFG, VariableOfIncompleteType) { + const char *Code = "template void f() {\n" + " class Undefined;\n" + " Undefined u;\n" + "}\n"; + EXPECT_EQ(BuiltCFG, BuildCFG(Code)); +} + } // namespace } // namespace analysis } // namespace clang ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D29117: SPARC: allow usage of floating-point registers in inline ASM
pboettch added a comment. On SparcV8 there is no %e register. Regarding soft-float, good question, I'll try. How do I create full-context-patches? Does this mean just more context lines? Like 500 or 1000 lines? https://reviews.llvm.org/D29117 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30685: [include-fixer] Remove line number from Symbol identity
sammccall created this revision. Remove line number from Symbol identity. For our purposes (include-fixer and clangd autocomplete), function overloads within the same header should mostly be treated as a single combined symbol. We may want to track individual occurrences (line number, full type info) and aggregate this during mapreduce, but that's not done here. https://reviews.llvm.org/D30685 Files: include-fixer/IncludeFixer.cpp include-fixer/find-all-symbols/FindAllMacros.cpp include-fixer/find-all-symbols/FindAllSymbols.cpp include-fixer/find-all-symbols/SymbolInfo.cpp include-fixer/find-all-symbols/SymbolInfo.h include-fixer/tool/ClangIncludeFixer.cpp test/include-fixer/Inputs/fake_yaml_db.yaml test/include-fixer/Inputs/merge/a.yaml test/include-fixer/Inputs/merge/b.yaml test/include-fixer/merge.test unittests/include-fixer/IncludeFixerTest.cpp unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp Index: unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp === --- unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp +++ unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp @@ -42,14 +42,14 @@ Symbols[Entry.first] += Entry.second; } - bool hasSymbol(const SymbolInfo &Symbol) const { + int hasSymbol(const SymbolInfo &Symbol) const { auto it = Symbols.find(Symbol); -return it != Symbols.end() && it->second.Seen > 0; +return it == Symbols.end() ? 0 : it->second.Seen; } - bool hasUse(const SymbolInfo &Symbol) const { + int hasUse(const SymbolInfo &Symbol) const { auto it = Symbols.find(Symbol); -return it != Symbols.end() && it->second.Used > 0; +return it == Symbols.end() ? 0 : it->second.Used; } private: @@ -86,9 +86,9 @@ std::string InternalCode = "#include \"private.inc\"\nclass Internal {};"; SymbolInfo InternalSymbol("Internal", SymbolInfo::SymbolKind::Class, - TopHeader, 2, {}); + TopHeader, {}); SymbolInfo IncSymbol("IncHeaderClass", SymbolInfo::SymbolKind::Class, - TopHeader, 1, {}); + TopHeader, {}); InMemoryFileSystem->addFile( IncHeader, 0, llvm::MemoryBuffer::getMemBuffer(IncHeaderCode)); InMemoryFileSystem->addFile(InternalHeader, 0, @@ -120,9 +120,9 @@ InMemoryFileSystem->addFile( DirtyHeader, 0, llvm::MemoryBuffer::getMemBuffer(DirtyHeaderContent)); SymbolInfo DirtyMacro("INTERNAL", SymbolInfo::SymbolKind::Macro, - CleanHeader, 1, {}); + CleanHeader, {}); SymbolInfo DirtySymbol("ExtraInternal", SymbolInfo::SymbolKind::Class, - CleanHeader, 2, {}); + CleanHeader, {}); #endif // _MSC_VER && __MINGW32__ Content += "\n" + MainCode.str(); InMemoryFileSystem->addFile(FileName, 0, @@ -155,16 +155,16 @@ runFindAllSymbols(Header, Main); SymbolInfo Symbol = - SymbolInfo("xargc", SymbolInfo::SymbolKind::Variable, HeaderName, 2, {}); + SymbolInfo("xargc", SymbolInfo::SymbolKind::Variable, HeaderName, {}); EXPECT_TRUE(hasSymbol(Symbol)); EXPECT_TRUE(hasUse(Symbol)); - Symbol = SymbolInfo("", SymbolInfo::SymbolKind::Variable, HeaderName, 4, + Symbol = SymbolInfo("", SymbolInfo::SymbolKind::Variable, HeaderName, {{SymbolInfo::ContextType::Namespace, "na"}}); EXPECT_TRUE(hasSymbol(Symbol)); EXPECT_TRUE(hasUse(Symbol)); - Symbol = SymbolInfo("", SymbolInfo::SymbolKind::Variable, HeaderName, 5, + Symbol = SymbolInfo("", SymbolInfo::SymbolKind::Variable, HeaderName, {{SymbolInfo::ContextType::Namespace, "nb"}, {SymbolInfo::ContextType::Namespace, "na"}}); EXPECT_TRUE(hasSymbol(Symbol)); @@ -188,12 +188,12 @@ runFindAllSymbols(Header, Main); SymbolInfo Symbol = - SymbolInfo("C_Func", SymbolInfo::SymbolKind::Function, HeaderName, 3, {}); + SymbolInfo("C_Func", SymbolInfo::SymbolKind::Function, HeaderName, {}); EXPECT_TRUE(hasSymbol(Symbol)); EXPECT_TRUE(hasUse(Symbol)); Symbol = - SymbolInfo("C_struct", SymbolInfo::SymbolKind::Class, HeaderName, 4, {}); + SymbolInfo("C_struct", SymbolInfo::SymbolKind::Class, HeaderName, {}); EXPECT_TRUE(hasSymbol(Symbol)); EXPECT_TRUE(hasUse(Symbol)); } @@ -219,16 +219,16 @@ runFindAllSymbols(Header, Main); SymbolInfo Symbol = - SymbolInfo("Glob", SymbolInfo::SymbolKind::Class, HeaderName, 2, {}); + SymbolInfo("Glob", SymbolInfo::SymbolKind::Class, HeaderName, {}); EXPECT_TRUE(hasSymbol(Symbol)); EXPECT_TRUE(hasUse(Symbol)); - Symbol = SymbolInfo("A", SymbolInfo::SymbolKind::Class, HeaderName, 6, + Symbol = SymbolInfo("A", SymbolInfo::SymbolKind::Class, HeaderName, {{SymbolInfo::ContextT
r297131 - [AST/ObjC] Make ObjCCategoryImplDecl consistent with ObjCCategoryDecl and use the category name as its DeclName
Author: akirtzidis Date: Tue Mar 7 03:26:07 2017 New Revision: 297131 URL: http://llvm.org/viewvc/llvm-project?rev=297131&view=rev Log: [AST/ObjC] Make ObjCCategoryImplDecl consistent with ObjCCategoryDecl and use the category name as its DeclName This also addresses the badness in ObjCCategoryImplDecl's API, which was hiding NamedDecl's APIs with different meaning. Modified: cfe/trunk/include/clang/AST/DeclObjC.h cfe/trunk/lib/AST/Decl.cpp cfe/trunk/lib/AST/Mangle.cpp cfe/trunk/lib/CodeGen/CGDebugInfo.cpp cfe/trunk/lib/Serialization/ASTReaderDecl.cpp cfe/trunk/lib/Serialization/ASTWriterDecl.cpp cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp cfe/trunk/test/Index/Core/index-source.m cfe/trunk/test/Index/Core/index-subkinds.m cfe/trunk/test/Misc/ast-dump-decl.m Modified: cfe/trunk/include/clang/AST/DeclObjC.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=297131&r1=297130&r2=297131&view=diff == --- cfe/trunk/include/clang/AST/DeclObjC.h (original) +++ cfe/trunk/include/clang/AST/DeclObjC.h Tue Mar 7 03:26:07 2017 @@ -2320,11 +2320,9 @@ class ObjCImplDecl : public ObjCContaine protected: ObjCImplDecl(Kind DK, DeclContext *DC, ObjCInterfaceDecl *classInterface, + IdentifierInfo *Id, SourceLocation nameLoc, SourceLocation atStartLoc) -: ObjCContainerDecl(DK, DC, -classInterface? classInterface->getIdentifier() - : nullptr, -nameLoc, atStartLoc), +: ObjCContainerDecl(DK, DC, Id, nameLoc, atStartLoc), ClassInterface(classInterface) {} public: @@ -2386,9 +2384,6 @@ public: class ObjCCategoryImplDecl : public ObjCImplDecl { void anchor() override; - // Category name - IdentifierInfo *Id; - // Category name location SourceLocation CategoryNameLoc; @@ -2396,8 +2391,9 @@ class ObjCCategoryImplDecl : public ObjC ObjCInterfaceDecl *classInterface, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation CategoryNameLoc) -: ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc), - Id(Id), CategoryNameLoc(CategoryNameLoc) {} +: ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id, + nameLoc, atStartLoc), + CategoryNameLoc(CategoryNameLoc) {} public: static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, @@ -2407,37 +2403,10 @@ public: SourceLocation CategoryNameLoc); static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID); - /// getIdentifier - Get the identifier that names the category - /// interface associated with this implementation. - /// FIXME: This is a bad API, we are hiding NamedDecl::getIdentifier() - /// with a different meaning. For example: - /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier() - /// returns the class interface name, whereas - /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier() - /// returns the category name. - IdentifierInfo *getIdentifier() const { -return Id; - } - void setIdentifier(IdentifierInfo *II) { Id = II; } - ObjCCategoryDecl *getCategoryDecl() const; SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; } - /// getName - Get the name of identifier for the class interface associated - /// with this implementation as a StringRef. - // - // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different - // meaning. - StringRef getName() const { return Id ? Id->getName() : StringRef(); } - - /// @brief Get the name of the class associated with this interface. - // - // FIXME: Deprecated, move clients to getName(). - std::string getNameAsString() const { -return getName(); - } - static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCCategoryImpl;} @@ -2493,7 +2462,10 @@ class ObjCImplementationDecl : public Ob SourceLocation superLoc = SourceLocation(), SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation()) -: ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc), +: ObjCImplDecl(ObjCImplementation, DC, classInterface, + classInterface ? classInterface->getIdentifier() + : nullptr, + nameLoc, atStartLoc), SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc), IvarInitializers(nullptr), NumIvarInitializers(0), Modified: cfe/trunk/l
r297133 - [index] Mark categories of test classes with the 'UnitTest' symbol property as well.
Author: akirtzidis Date: Tue Mar 7 03:38:08 2017 New Revision: 297133 URL: http://llvm.org/viewvc/llvm-project?rev=297133&view=rev Log: [index] Mark categories of test classes with the 'UnitTest' symbol property as well. Modified: cfe/trunk/lib/Index/IndexSymbol.cpp cfe/trunk/test/Index/Core/index-subkinds.m Modified: cfe/trunk/lib/Index/IndexSymbol.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexSymbol.cpp?rev=297133&r1=297132&r2=297133&view=diff == --- cfe/trunk/lib/Index/IndexSymbol.cpp (original) +++ cfe/trunk/lib/Index/IndexSymbol.cpp Tue Mar 7 03:38:08 2017 @@ -185,10 +185,18 @@ SymbolInfo index::getSymbolInfo(const De Info.Lang = SymbolLanguage::ObjC; break; case Decl::ObjCCategory: -case Decl::ObjCCategoryImpl: +case Decl::ObjCCategoryImpl: { Info.Kind = SymbolKind::Extension; Info.Lang = SymbolLanguage::ObjC; + const ObjCInterfaceDecl *ClsD = nullptr; + if (auto *CatD = dyn_cast(D)) +ClsD = CatD->getClassInterface(); + else +ClsD = cast(D)->getClassInterface(); + if (isUnitTestCase(ClsD)) +Info.Properties |= (unsigned)SymbolProperty::UnitTest; break; +} case Decl::ObjCMethod: if (cast(D)->isInstanceMethod()) { const ObjCMethodDecl *MD = cast(D); Modified: cfe/trunk/test/Index/Core/index-subkinds.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Core/index-subkinds.m?rev=297133&r1=297132&r2=297133&view=diff == --- cfe/trunk/test/Index/Core/index-subkinds.m (original) +++ cfe/trunk/test/Index/Core/index-subkinds.m Tue Mar 7 03:38:08 2017 @@ -28,11 +28,11 @@ // CHECK: [[@LINE+3]]:12 | class(test)/ObjC | MyTestCase | c:objc(cs)MyTestCase | _OBJC_CLASS_$_MyTestCase | Ref,RelExt,RelCont | rel: 1 // CHECK-NEXT: RelExt,RelCont | cat | c:objc(cy)MyTestCase@cat -// CHECK: [[@LINE+1]]:23 | extension/ObjC | cat | c:objc(cy)MyTestCase@cat | | Decl | rel: 0 +// CHECK: [[@LINE+1]]:23 | extension(test)/ObjC | cat | c:objc(cy)MyTestCase@cat | | Decl | rel: 0 @interface MyTestCase(cat) @end // CHECK: [[@LINE+2]]:17 | class(test)/ObjC | MyTestCase | c:objc(cs)MyTestCase | _OBJC_CLASS_$_MyTestCase | Ref,RelCont | rel: 1 -// CHECK: [[@LINE+1]]:28 | extension/ObjC | cat | c:objc(cy)MyTestCase@cat | | Def | rel: 0 +// CHECK: [[@LINE+1]]:28 | extension(test)/ObjC | cat | c:objc(cy)MyTestCase@cat | | Def | rel: 0 @implementation MyTestCase(cat) // CHECK: [[@LINE+1]]:9 | instance-method(test)/ObjC | testInCat | c:objc(cs)MyTestCase(im)testInCat | -[MyTestCase(cat) testInCat] | Def,Dyn,RelChild | rel: 1 - (void)testInCat {} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30166: Honor __unaligned in codegen for declarations and expressions
rogfer01 added a comment. Ping? :-) Kind regards https://reviews.llvm.org/D30166 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28670: [ObjC] Disallow vector parameters and return values in Objective-C methods on older X86 targets
arphaman added inline comments. Comment at: lib/Sema/SemaDeclObjC.cpp:4312 + for (const ParmVarDecl *P : Method->parameters()) { +if (P->getType()->isVectorType()) { + Loc = P->getLocStart(); bruno wrote: > Assuming objc/c++ can pass/return these, the current check wouldn't be enough > to cover x86_64 ABI cases where small (< 8 bytes) trivial classes containing > vector types are directly passed / returned as vector types. You might want > to check if that applies here. > > See test/CodeGenCXX/x86_64-arguments-avx.cpp for examples (and x86_64 abi > doc, item 3.2.3) It seems that on X86 all the troubling aggregates are passed by pointer anyway, and we don't warn for X86_64 at all. The only aggregates that seem to use registers for Objective-C methods are the ones that don't use vector registers. Repository: rL LLVM https://reviews.llvm.org/D28670 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28670: [ObjC] Disallow vector parameters and return values in Objective-C methods on older X86 targets
arphaman updated this revision to Diff 90832. arphaman marked an inline comment as done. arphaman added a comment. Add a test for non-ext vector type Repository: rL LLVM https://reviews.llvm.org/D28670 Files: include/clang/AST/DeclBase.h include/clang/Basic/DiagnosticSemaKinds.td lib/AST/DeclBase.cpp lib/Sema/SemaDeclObjC.cpp test/SemaObjC/x86-method-vector-values.m Index: test/SemaObjC/x86-method-vector-values.m === --- /dev/null +++ test/SemaObjC/x86-method-vector-values.m @@ -0,0 +1,132 @@ +// RUN: %clang_cc1 -verify -DMAC -triple=i686-apple-macosx10.10 -Wno-objc-root-class %s +// RUN: %clang_cc1 -verify -DMAC -triple=i686-apple-macosx10.4 -Wno-objc-root-class %s +// RUN: %clang_cc1 -verify -DMAC -triple=i686-apple-darwin14 -Wno-objc-root-class %s +// RUN: %clang_cc1 -verify -triple=i686-apple-ios8 -Wno-objc-root-class %s + +// RUN: %clang_cc1 -verify -DALLOW -DMAC -triple=i686-apple-macosx10.11 -Wno-objc-root-class %s +// RUN: %clang_cc1 -verify -DALLOW -DMAC -triple=i686-apple-darwin15 -Wno-objc-root-class %s +// RUN: %clang_cc1 -verify -DALLOW -DIOS -triple=i686-apple-ios9 -Wno-objc-root-class %s +// RUN: %clang_cc1 -verify -DALLOW -DOTHER -triple=i686-apple-watchos -Wno-objc-root-class %s +// RUN: %clang_cc1 -verify -DALLOW -DOTHER -triple=i686-apple-tvos -Wno-objc-root-class %s + +// RUN: %clang_cc1 -verify -DALLOW -DOTHER -triple=x86_64-apple-macosx10.10 -Wno-objc-root-class %s + +// rdar://21662309 + +typedef __attribute__((__ext_vector_type__(3))) float float3; + +typedef float __m128 __attribute__((__vector_size__(16))); + +struct Aggregate { __m128 v; }; +struct AggregateFloat { float v; }; + +#define AVAILABLE_MACOS_10_10 __attribute__((availability(macos, introduced = 10.10))) +#define AVAILABLE_MACOS_10_11 __attribute__((availability(macos, introduced = 10.11))) + +#define AVAILABLE_IOS_8 __attribute__((availability(ios, introduced = 8.0))) +#define AVAILABLE_IOS_9 __attribute__((availability(ios, introduced = 9.0))) + +@interface VectorMethods + +-(void)takeVector:(float3)v; // there should be no diagnostic at declaration +-(void)takeM128:(__m128)v; + +@end + +@implementation VectorMethods + +#ifndef ALLOW + +-(void)takeVector:(float3)v { +#ifdef MAC + // expected-error@-2 {{'float3' (vector of 3 'float' values) parameter type is unsupported; support for vector types for this target is introduced in macOS 10.11}} +#else + // expected-error@-4 {{'float3' (vector of 3 'float' values) parameter type is unsupported; support for vector types for this target is introduced in iOS 9}} +#endif +} + +-(float3)retVector { // expected-error {{'float3' (vector of 3 'float' values) return type is unsupported}} +} + +-(void)takeVector2:(float3)v AVAILABLE_MACOS_10_10 { // expected-error {{'float3' (vector of 3 'float' values) parameter type is unsupported}} +} + +-(void)takeVector3:(float3)v AVAILABLE_MACOS_10_11 { // expected-error {{'float3' (vector of 3 'float' values) parameter type is unsupported}} +} + +-(void)takeVector4:(float3)v AVAILABLE_IOS_8 { // expected-error {{'float3' (vector of 3 'float' values) parameter type is unsupported}} +} + +-(void)takeVector5:(float3)v AVAILABLE_IOS_9 { // expected-error {{'float3' (vector of 3 'float' values) parameter type is unsupported}} +} + +- (__m128)retM128 { // expected-error {{'__m128' (vector of 4 'float' values) return type is unsupported}} +} + +- (void)takeM128:(__m128)v { // expected-error {{'__m128' (vector of 4 'float' values) parameter type is unsupported}} +} + +#else + +-(void)takeVector:(float3)v { +} + +-(float3)retVector { + return 0; +} + +- (__m128)retM128 { + __m128 value; + return value; +} + +- (void)takeM128:(__m128)v { +} + +-(void)takeVector2:(float3)v AVAILABLE_MACOS_10_10 { +#ifdef MAC +// expected-error@-2 {{'float3' (vector of 3 'float' values) parameter type is unsupported}} +#endif +} + +- (__m128)retM128_2 AVAILABLE_MACOS_10_10 { +#ifdef MAC +// expected-error@-2 {{'__m128' (vector of 4 'float' values) return type is unsupported}} +#endif + __m128 value; + return value; +} + +-(void)takeVector3:(float3)v AVAILABLE_MACOS_10_11 { // no error +} + +-(void)takeVector4:(float3)v AVAILABLE_IOS_8 { +#ifdef IOS + // expected-error@-2 {{'float3' (vector of 3 'float' values) parameter type is unsupported}} +#endif +} + +-(void)takeVector5:(float3)v AVAILABLE_IOS_9 { // no error +} + +#ifdef OTHER +// expected-no-diagnostics +#endif + +#endif + +-(void)doStuff:(int)m { // no error +} + +-(struct Aggregate)takesAndRetVectorInAggregate:(struct Aggregate)f { // no error + struct Aggregate result; + return result; +} + +-(struct AggregateFloat)takesAndRetFloatInAggregate:(struct AggregateFloat)f { // no error + struct AggregateFloat result; + return result; +} + + +@end Index: lib/Sema/SemaDeclObjC.cpp === --- lib/Sema/SemaDeclObjC.cpp +++ lib/Sema/SemaDeclObjC.cpp @@ -4302,6 +4302,48
[PATCH] D25866: [Sema] Support implicit scalar to vector conversions
sdardis marked 3 inline comments as done. sdardis added a comment. Thanks for getting back to this. I've traced the appearance of the ext_vector type to a piece of code that only produces ext-vector types for comparisons. I'm presuming that's wrong when clang is producing vectors implicitly in the non-OpenCL case. I'll update the diff once I've changed that. Comment at: test/Sema/vector-gcc-compat.c:61 + //match. + v2i64_r = v2i64_a == 1; // expected-warning {{incompatible vector types assigning to 'v2i64' (vector of 2 'long long' values) from 'long __attribute__((ext_vector_type(2)))' (vector of 2 'long' values)}} + v2i64_r = v2i64_a != 1; // expected-warning {{incompatible vector types assigning to 'v2i64' (vector of 2 'long long' values) from 'long __attribute__((ext_vector_type(2)))' (vector of 2 'long' values)}} bruno wrote: > Can you double check where 'long __attribute__((ext_vector_type(2)))' comes > from? > > We have regressed in the past year in the way ext-vector interacts with > non-ext-vectors, and I don't wanna make it worse until we actually have time > to fix that; there's a lot of code out there relying on bitcasts between > ext-vectors and non-ext-vectors to bridge between intrinsics headers and > ext-vector code. Sema::CheckVectorCompareOperands calls Sema::GetSignedVectorType which only returns ext-vector types. I presume that is now incorrect if we're producing vectors from literal scalars in the non OpenCL case. 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] D29117: SPARC: allow usage of floating-point registers in inline ASM
sdardis added a comment. > How do I create full-context-patches? Does this mean just more context lines? > Like 500 or 1000 lines? http://llvm.org/docs/Phabricator.html#requesting-a-review-via-the-web-interface https://reviews.llvm.org/D29117 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30691: [analyzer] Support for naive cross translational unit analysis
xazax.hun created this revision. Herald added a subscriber: mgorny. This patch adds support for naive cross translational unit analysis. The aim of this patch is to be minimal to enable the development of the feature on the top of tree. This patch should be an NFC in case XTUDir is not provided by the user. When XTUDir is provided: - In case a function definition is not available it will be looked up from a textual index, whether it was available in another TU. - The AST dump of the other TU will be loaded and the function definition will be inlined. One of the main limitations is that the coverage pattern of the analysis will change when this feature is enabled. For this reason in the future it might be better to include some heuristics to prefer examining shorter execution paths to the longer ones. Until than this feature is not recommended to be turned on by users unless they already fixed the important issues with this feature turned off. We will cover more detailed analysis of this patch soon in our EuroLLVM talk: http://llvm.org/devmtg/2017-03//2017/02/20/accepted-sessions.html#7 We will talk about how this works and the memory usage, analysis time, coverage pattern change, limitations of the ASTImporter, how the length of the bugpaths changed and a lot more. Feel free to skip the review after the talk, but we wanted to make the code available in an easy to review format before the conference. Repository: rL LLVM https://reviews.llvm.org/D30691 Files: include/clang/AST/ASTContext.h include/clang/AST/Decl.h include/clang/AST/Mangle.h include/clang/StaticAnalyzer/Core/AnalyzerOptions.h include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h lib/AST/ASTContext.cpp lib/AST/ASTImporter.cpp lib/AST/ItaniumMangle.cpp lib/Basic/SourceManager.cpp lib/StaticAnalyzer/Core/AnalyzerOptions.cpp lib/StaticAnalyzer/Core/CMakeLists.txt lib/StaticAnalyzer/Core/CallEvent.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp test/Analysis/Inputs/externalFnMap.txt test/Analysis/Inputs/xtu-chain.cpp test/Analysis/Inputs/xtu-other.cpp test/Analysis/xtu-main.cpp tools/CMakeLists.txt tools/clang-cmdline-arch-extractor/CMakeLists.txt tools/clang-cmdline-arch-extractor/ClangCmdlineArchExtractor.cpp tools/clang-func-mapping/CMakeLists.txt tools/clang-func-mapping/ClangFnMapGen.cpp tools/scan-build-py/libscanbuild/runner.py tools/xtu-analysis/xtu-analyze.py tools/xtu-analysis/xtu-build.py Index: tools/xtu-analysis/xtu-build.py === --- /dev/null +++ tools/xtu-analysis/xtu-build.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python + +import argparse +import io +import json +import multiprocessing +import os +import re +import signal +import subprocess +import string + +threading_factor = int(multiprocessing.cpu_count() * 1.5) +timeout = 86400 + +parser = argparse.ArgumentParser( +description='Executes 1st pass of XTU analysis') +parser.add_argument('-b', required=True, dest='buildlog', +metavar='build.json', +help='Use a JSON Compilation Database') +parser.add_argument('-p', metavar='preanalyze-dir', dest='xtuindir', +help='Use directory for generating preanalyzation data ' + '(default=".xtu")', +default='.xtu') +parser.add_argument('-j', metavar='threads', dest='threads', +help='Number of threads used (default=' + +str(threading_factor) + ')', +default=threading_factor) +parser.add_argument('-v', dest='verbose', action='store_true', +help='Verbose output of every command executed') +parser.add_argument('--clang-path', metavar='clang-path', dest='clang_path', +help='Set path of clang binaries to be used ' + '(default taken from CLANG_PATH envvar)', +default=os.environ.get('CLANG_PATH')) +parser.add_argument('--timeout', metavar='N', +help='Timeout for build in seconds (default: %d)' % +timeout, +default=timeout) +mainargs = parser.parse_args() + +if mainargs.clang_path is None: +clang_path = '' +else: +clang_path = os.path.abspath(mainargs.clang_path) +if mainargs.verbose: +print 'XTU uses clang dir: ' + \ +(clang_path if clang_path != '' else '') + +buildlog_file = open(mainargs.buildlog, 'r') +buildlog = json.load(buildlog_file) +buildlog_file.close() + +src_pattern = re.compile('.*\.(C|c|cc|cpp|cxx|ii|m|mm)$', re.IGNORECASE) +src_2_dir = {} +src_2_cmd = {} +src_order = [] +cmd_2_src = {} +cmd_order = [] +for step in buildlog: +if src_pattern.match(step['file']): +if step['file'] not in src_2_dir: +src_2_dir[step['file']] = step['directory'] +
[PATCH] D30688: [clang-format] Support namespaces ending in semicolon
djasper accepted this revision. djasper added a comment. This revision is now accepted and ready to land. Minor nit, otherwise looks good. Comment at: lib/Format/NamespaceEndCommentsFixer.cpp:152 +const FormatToken *EndCommentNextTok = EndCommentPrevTok->Next; +if (EndCommentNextTok && EndCommentNextTok->is(tok::comment)) { + EndCommentNextTok = EndCommentNextTok->Next; No braces around single-statement ifs. https://reviews.llvm.org/D30688 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30688: [clang-format] Support namespaces ending in semicolon
krasimir updated this revision to Diff 90839. krasimir added a comment. - Remove braces https://reviews.llvm.org/D30688 Files: lib/Format/NamespaceEndCommentsFixer.cpp unittests/Format/NamespaceEndCommentsFixerTest.cpp Index: unittests/Format/NamespaceEndCommentsFixerTest.cpp === --- unittests/Format/NamespaceEndCommentsFixerTest.cpp +++ unittests/Format/NamespaceEndCommentsFixerTest.cpp @@ -184,6 +184,34 @@ "}\n" "}\n" "}")); + + // Adds an end comment after a semicolon. + EXPECT_EQ("namespace {\n" +" int i;\n" +" int j;\n" +"};// namespace", +fixNamespaceEndComments("namespace {\n" +" int i;\n" +" int j;\n" +"};")); + EXPECT_EQ("namespace A {\n" +" int i;\n" +" int j;\n" +"};// namespace A", +fixNamespaceEndComments("namespace A {\n" +" int i;\n" +" int j;\n" +"};")); + EXPECT_EQ("namespace A {\n" +" int i;\n" +" int j;\n" +"};// namespace A\n" +"// unrelated", +fixNamespaceEndComments("namespace A {\n" +" int i;\n" +" int j;\n" +"};\n" +"// unrelated")); } TEST_F(NamespaceEndCommentsFixerTest, AddsNewlineIfNeeded) { @@ -220,13 +248,33 @@ " int j;\n" " int k;\n" "}")); + EXPECT_EQ("namespace {\n" +" int i;\n" +" int j;\n" +"};// namespace\n" +"int k;", +fixNamespaceEndComments("namespace {\n" +" int i;\n" +" int j;\n" +"};int k;")); + EXPECT_EQ("namespace {\n" +" int i;\n" +" int j;\n" +"};// namespace\n" +";", +fixNamespaceEndComments("namespace {\n" +" int i;\n" +" int j;\n" +"};;")); } TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddEndCommentForShortNamespace) { EXPECT_EQ("namespace {}", fixNamespaceEndComments("namespace {}")); EXPECT_EQ("namespace A {}", fixNamespaceEndComments("namespace A {}")); EXPECT_EQ("namespace A { a }", fixNamespaceEndComments("namespace A { a }")); + EXPECT_EQ("namespace A { a };", +fixNamespaceEndComments("namespace A { a };")); } TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterUnaffectedRBrace) { @@ -238,6 +286,14 @@ "}", // The range (16, 3) spans the 'int' above. /*Ranges=*/{1, tooling::Range(16, 3)})); + EXPECT_EQ("namespace A {\n" +" int i;\n" +"};", +fixNamespaceEndComments("namespace A {\n" +" int i;\n" +"};", +// The range (16, 3) spans the 'int' above. +/*Ranges=*/{1, tooling::Range(16, 3)})); } TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterRBraceInPPDirective) { @@ -276,6 +332,18 @@ fixNamespaceEndComments("namespace A::B {\n" " int i;\n" "} // end namespace A::B")); + EXPECT_EQ("namespace A {\n" +" int i;\n" +"}; // end namespace A", +fixNamespaceEndComments("namespace A {\n" +" int i;\n" +"}; // end namespace A")); + EXPECT_EQ("namespace {\n" +" int i;\n" +"}; /* unnamed namespace */", +fixNamespaceEndComments("namespace {\n" +" int i;\n" +"}; /* unnamed namespace */")); } TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndLineComment) { @@ -309,10 +377,17 @@ fixNamespaceEndComments("namespace A {\n" " int i;\n" "} // banamespace A")); - + EXPECT_EQ("namespace A {\n" +" int i;\n" +"}; // namespace A", +fixNamespaceEndComments("namespace A {\n" +" int i;\n" +
[PATCH] D30688: [clang-format] Support namespaces ending in semicolon
This revision was automatically updated to reflect the committed changes. Closed by commit rL297140: [clang-format] Support namespaces ending in semicolon (authored by krasimir). Changed prior to commit: https://reviews.llvm.org/D30688?vs=90839&id=90841#toc Repository: rL LLVM https://reviews.llvm.org/D30688 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 @@ -139,20 +139,34 @@ if (RBraceTok->Finalized) continue; RBraceTok->Finalized = true; +const FormatToken *EndCommentPrevTok = RBraceTok; +// Namespaces often end with '};'. In that case, attach namespace end +// comments to the semicolon tokens. +if (RBraceTok->Next && RBraceTok->Next->is(tok::semi)) { + EndCommentPrevTok = RBraceTok->Next; +} +// The next token in the token stream after the place where the end comment +// token must be. This is either the next token on the current line or the +// first token on the next line. +const FormatToken *EndCommentNextTok = EndCommentPrevTok->Next; +if (EndCommentNextTok && EndCommentNextTok->is(tok::comment)) + EndCommentNextTok = EndCommentNextTok->Next; +if (!EndCommentNextTok && I + 1 < E) + EndCommentNextTok = AnnotatedLines[I + 1]->First; +bool AddNewline = EndCommentNextTok && + EndCommentNextTok->NewlinesBefore == 0 && + EndCommentNextTok->isNot(tok::eof); const std::string NamespaceName = computeName(NamespaceTok); -bool AddNewline = (I + 1 < E) && - AnnotatedLines[I + 1]->First->NewlinesBefore == 0 && - AnnotatedLines[I + 1]->First->isNot(tok::eof); const std::string EndCommentText = computeEndCommentText(NamespaceName, AddNewline); -if (!hasEndComment(RBraceTok)) { +if (!hasEndComment(EndCommentPrevTok)) { bool isShort = I - StartLineIndex <= kShortNamespaceMaxLines + 1; if (!isShort) -addEndComment(RBraceTok, EndCommentText, SourceMgr, &Fixes); +addEndComment(EndCommentPrevTok, EndCommentText, SourceMgr, &Fixes); continue; } -if (!validEndComment(RBraceTok, NamespaceName)) - updateEndComment(RBraceTok, EndCommentText, SourceMgr, &Fixes); +if (!validEndComment(EndCommentPrevTok, NamespaceName)) + updateEndComment(EndCommentPrevTok, EndCommentText, SourceMgr, &Fixes); } return Fixes; } Index: cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp === --- cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp +++ cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp @@ -184,6 +184,34 @@ "}\n" "}\n" "}")); + + // Adds an end comment after a semicolon. + EXPECT_EQ("namespace {\n" +" int i;\n" +" int j;\n" +"};// namespace", +fixNamespaceEndComments("namespace {\n" +" int i;\n" +" int j;\n" +"};")); + EXPECT_EQ("namespace A {\n" +" int i;\n" +" int j;\n" +"};// namespace A", +fixNamespaceEndComments("namespace A {\n" +" int i;\n" +" int j;\n" +"};")); + EXPECT_EQ("namespace A {\n" +" int i;\n" +" int j;\n" +"};// namespace A\n" +"// unrelated", +fixNamespaceEndComments("namespace A {\n" +" int i;\n" +" int j;\n" +"};\n" +"// unrelated")); } TEST_F(NamespaceEndCommentsFixerTest, AddsNewlineIfNeeded) { @@ -220,13 +248,33 @@ " int j;\n" " int k;\n" "}")); + EXPECT_EQ("namespace {\n" +" int i;\n" +" int j;\n" +"};// namespace\n" +"int k;", +fixNamespaceEndComments("namespace {\n" +" int i;\n" +" int j;\n" +"};int k;")); + EXPECT_EQ("namespace {\n" +" int i;\n" +" int j;\n" +"};// namespace\n" +";", +fixNamespaceEndComments("namespace {\n" +" in
r297140 - [clang-format] Support namespaces ending in semicolon
Author: krasimir Date: Tue Mar 7 08:07:43 2017 New Revision: 297140 URL: http://llvm.org/viewvc/llvm-project?rev=297140&view=rev Log: [clang-format] Support namespaces ending in semicolon Summary: This patch adds support for namespaces ending in semicolon to the namespace comment fixer. source: ``` namespace A { int i; int j; }; ``` clang-format before: ``` namespace A { int i; int j; } // namespace A; ``` clang-format after: ``` namespace A { int i; int j; }; // namespace A ``` Reviewers: djasper Reviewed By: djasper Subscribers: cfe-commits, klimek Differential Revision: https://reviews.llvm.org/D30688 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=297140&r1=297139&r2=297140&view=diff == --- cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp (original) +++ cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp Tue Mar 7 08:07:43 2017 @@ -139,20 +139,34 @@ tooling::Replacements NamespaceEndCommen if (RBraceTok->Finalized) continue; RBraceTok->Finalized = true; +const FormatToken *EndCommentPrevTok = RBraceTok; +// Namespaces often end with '};'. In that case, attach namespace end +// comments to the semicolon tokens. +if (RBraceTok->Next && RBraceTok->Next->is(tok::semi)) { + EndCommentPrevTok = RBraceTok->Next; +} +// The next token in the token stream after the place where the end comment +// token must be. This is either the next token on the current line or the +// first token on the next line. +const FormatToken *EndCommentNextTok = EndCommentPrevTok->Next; +if (EndCommentNextTok && EndCommentNextTok->is(tok::comment)) + EndCommentNextTok = EndCommentNextTok->Next; +if (!EndCommentNextTok && I + 1 < E) + EndCommentNextTok = AnnotatedLines[I + 1]->First; +bool AddNewline = EndCommentNextTok && + EndCommentNextTok->NewlinesBefore == 0 && + EndCommentNextTok->isNot(tok::eof); const std::string NamespaceName = computeName(NamespaceTok); -bool AddNewline = (I + 1 < E) && - AnnotatedLines[I + 1]->First->NewlinesBefore == 0 && - AnnotatedLines[I + 1]->First->isNot(tok::eof); const std::string EndCommentText = computeEndCommentText(NamespaceName, AddNewline); -if (!hasEndComment(RBraceTok)) { +if (!hasEndComment(EndCommentPrevTok)) { bool isShort = I - StartLineIndex <= kShortNamespaceMaxLines + 1; if (!isShort) -addEndComment(RBraceTok, EndCommentText, SourceMgr, &Fixes); +addEndComment(EndCommentPrevTok, EndCommentText, SourceMgr, &Fixes); continue; } -if (!validEndComment(RBraceTok, NamespaceName)) - updateEndComment(RBraceTok, EndCommentText, SourceMgr, &Fixes); +if (!validEndComment(EndCommentPrevTok, NamespaceName)) + updateEndComment(EndCommentPrevTok, EndCommentText, SourceMgr, &Fixes); } return Fixes; } Modified: cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp?rev=297140&r1=297139&r2=297140&view=diff == --- cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp (original) +++ cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp Tue Mar 7 08:07:43 2017 @@ -184,6 +184,34 @@ TEST_F(NamespaceEndCommentsFixerTest, Ad "}\n" "}\n" "}")); + + // Adds an end comment after a semicolon. + EXPECT_EQ("namespace {\n" +" int i;\n" +" int j;\n" +"};// namespace", +fixNamespaceEndComments("namespace {\n" +" int i;\n" +" int j;\n" +"};")); + EXPECT_EQ("namespace A {\n" +" int i;\n" +" int j;\n" +"};// namespace A", +fixNamespaceEndComments("namespace A {\n" +" int i;\n" +" int j;\n" +"};")); + EXPECT_EQ("namespace A {\n" +" int i;\n" +" int j;\n" +"};// namespace A\n" +"// unrelated", +fixNamespaceEndComments("namespace A {\n" +" int i;\n" +" int j;\n" +"};\n" +"// unrelated")); } TEST_F(Nam
[PATCH] D30693: [mips][msa] Remove range checks for non-immediate sld.[bhwd] instructions
smaksimovic created this revision. Removes immediate range checks for these instructions, since they have GPR rt as their input operand. https://reviews.llvm.org/D30693 Files: lib/Sema/SemaChecking.cpp test/CodeGen/builtins-mips-msa-error.c test/CodeGen/builtins-mips-msa.c Index: test/CodeGen/builtins-mips-msa.c === --- test/CodeGen/builtins-mips-msa.c +++ test/CodeGen/builtins-mips-msa.c @@ -698,6 +698,11 @@ v8i16_r = __msa_sld_h(v8i16_r, v8i16_a, 5); // CHECK: call <8 x i16> @llvm.mips.sld.h( v4i32_r = __msa_sld_w(v4i32_r, v4i32_a, 3); // CHECK: call <4 x i32> @llvm.mips.sld.w( v2i64_r = __msa_sld_d(v2i64_r, v2i64_a, 1); // CHECK: call <2 x i64> @llvm.mips.sld.d( + + v16i8_r = __msa_sld_b(v16i8_r, v16i8_a, 16); // CHECK: call <16 x i8> @llvm.mips.sld.b( + v8i16_r = __msa_sld_h(v8i16_r, v8i16_a, 8); // CHECK: call <8 x i16> @llvm.mips.sld.h( + v4i32_r = __msa_sld_w(v4i32_r, v4i32_a, 4); // CHECK: call <4 x i32> @llvm.mips.sld.w( + v2i64_r = __msa_sld_d(v2i64_r, v2i64_a, 2); // CHECK: call <2 x i64> @llvm.mips.sld.d( v16i8_r = __msa_sldi_b(v16i8_r, v16i8_a, 7); // CHECK: call <16 x i8> @llvm.mips.sldi.b( v8i16_r = __msa_sldi_h(v8i16_r, v8i16_a, 3); // CHECK: call <8 x i16> @llvm.mips.sldi.h( Index: test/CodeGen/builtins-mips-msa-error.c === --- test/CodeGen/builtins-mips-msa-error.c +++ test/CodeGen/builtins-mips-msa-error.c @@ -162,11 +162,6 @@ v8i16_r = __msa_shf_h(v8i16_a, 256); // CHECK: warning: argument should be a value from 0 to 255}} v4i32_r = __msa_shf_w(v4i32_a, 256); // CHECK: warning: argument should be a value from 0 to 255}} - v16i8_r = __msa_sld_b(v16i8_r, v16i8_a, 16); // expected-error {{argument should be a value from 0 to 15}} - v8i16_r = __msa_sld_h(v8i16_r, v8i16_a, 8); // expected-error {{argument should be a value from 0 to 7}} - v4i32_r = __msa_sld_w(v4i32_r, v4i32_a, 4); // expected-error {{argument should be a value from 0 to 3}} - v2i64_r = __msa_sld_d(v2i64_r, v2i64_a, 2); // expected-error {{argument should be a value from 0 to 1}} - v16i8_r = __msa_sldi_b(v16i8_r, v16i8_a, 16); // expected-error {{argument should be a value from 0 to 15}} v8i16_r = __msa_sldi_h(v8i16_r, v8i16_a, 8); // expected-error {{argument should be a value from 0 to 7}} v4i32_r = __msa_sldi_w(v4i32_r, v4i32_a, 4); // expected-error {{argument should be a value from 0 to 3}} @@ -358,11 +353,6 @@ v8i16_r = __msa_shf_h(v8i16_a, -1);// CHECK: warning: argument should be a value from 0 to 255}} v4i32_r = __msa_shf_w(v4i32_a, -1);// CHECK: warning: argument should be a value from 0 to 255}} - v16i8_r = __msa_sld_b(v16i8_r, v16i8_a, -17); // expected-error {{argument should be a value from 0 to 15}} - v8i16_r = __msa_sld_h(v8i16_r, v8i16_a, -8); // expected-error {{argument should be a value from 0 to 7}} - v4i32_r = __msa_sld_w(v4i32_r, v4i32_a, -4); // expected-error {{argument should be a value from 0 to 3}} - v2i64_r = __msa_sld_d(v2i64_r, v2i64_a, -2); // expected-error {{argument should be a value from 0 to 1}} - v16i8_r = __msa_sldi_b(v16i8_r, v16i8_a, -17); // expected-error {{argument should be a value from 0 to 15}} v8i16_r = __msa_sldi_h(v8i16_r, v8i16_a, -8); // expected-error {{argument should be a value from 0 to 7}} v4i32_r = __msa_sldi_w(v4i32_r, v4i32_a, -4); // expected-error {{argument should be a value from 0 to 3}} Index: lib/Sema/SemaChecking.cpp === --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -1619,28 +1619,24 @@ case Mips::BI__builtin_msa_copy_u_b: case Mips::BI__builtin_msa_insve_b: case Mips::BI__builtin_msa_splati_b: i = 1; l = 0; u = 15; break; - case Mips::BI__builtin_msa_sld_b: case Mips::BI__builtin_msa_sldi_b: i = 2; l = 0; u = 15; break; // These intrinsics take an unsigned 3 bit immediate. case Mips::BI__builtin_msa_copy_s_h: case Mips::BI__builtin_msa_copy_u_h: case Mips::BI__builtin_msa_insve_h: case Mips::BI__builtin_msa_splati_h: i = 1; l = 0; u = 7; break; - case Mips::BI__builtin_msa_sld_h: case Mips::BI__builtin_msa_sldi_h: i = 2; l = 0; u = 7; break; // These intrinsics take an unsigned 2 bit immediate. case Mips::BI__builtin_msa_copy_s_w: case Mips::BI__builtin_msa_copy_u_w: case Mips::BI__builtin_msa_insve_w: case Mips::BI__builtin_msa_splati_w: i = 1; l = 0; u = 3; break; - case Mips::BI__builtin_msa_sld_w: case Mips::BI__builtin_msa_sldi_w: i = 2; l = 0; u = 3; break; // These intrinsics take an unsigned 1 bit immediate. case Mips::BI__builtin_msa_copy_s_d: case Mips::BI__builtin_msa_copy_u_d: case Mips::BI__builtin_msa_insve_d: case Mips::BI__bui
[PATCH] D23418: [analyzer] Added a reusable constraint system to the CloneDetector
NoQ added a comment. I'm sorry for the delays; i'm humbly requesting a couple more weeks to get back to this awesome stuff. 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] D30157: [analyzer] Improve valist check
NoQ accepted this revision. NoQ added a comment. This revision is now accepted and ready to land. It's great to see things move out of alpha and finally become actually accessible to the majority of users. Thanks! https://reviews.llvm.org/D30157 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] r297149 - Let arm_section_length store the number of bytes.
Author: ed Date: Tue Mar 7 09:21:57 2017 New Revision: 297149 URL: http://llvm.org/viewvc/llvm-project?rev=297149&view=rev Log: Let arm_section_length store the number of bytes. Exception section data that we extract for DWARF gets stored as the offset and the number of bytes. For ARM exception info, we seem to deviate from this by storing the number of entries. Attempt to make this more consistent. By storing the number of bytes, we can get rid of the EHTEntry structure declared in AddressSpace.hpp. In UnwindCursor.hpp we already have another structure declared for the same purpose. Reviewed by:Keith Walker Differential Revision: https://reviews.llvm.org/D30681 Modified: libunwind/trunk/src/AddressSpace.hpp libunwind/trunk/src/UnwindCursor.hpp Modified: libunwind/trunk/src/AddressSpace.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/AddressSpace.hpp?rev=297149&r1=297148&r2=297149&view=diff == --- libunwind/trunk/src/AddressSpace.hpp (original) +++ libunwind/trunk/src/AddressSpace.hpp Tue Mar 7 09:21:57 2017 @@ -35,15 +35,11 @@ namespace libunwind { #include "Registers.hpp" #if _LIBUNWIND_ARM_EHABI -struct EHTEntry { - uint32_t functionOffset; - uint32_t unwindOpcodes; -}; #if defined(_LIBUNWIND_IS_BAREMETAL) // When statically linked on bare-metal, the symbols for the EH table are looked // up without going through the dynamic loader. -extern EHTEntry __exidx_start; -extern EHTEntry __exidx_end; +extern char __exidx_start; +extern char __exidx_end; #else #include #endif // !defined(_LIBUNWIND_IS_BAREMETAL) @@ -437,8 +433,7 @@ inline bool LocalAddressSpace::findUnwin } else if (phdr->p_type == PT_ARM_EXIDX) { uintptr_t exidx_start = pinfo->dlpi_addr + phdr->p_vaddr; cbdata->sects->arm_section = exidx_start; -cbdata->sects->arm_section_length = phdr->p_memsz / -sizeof(EHTEntry); +cbdata->sects->arm_section_length = phdr->p_memsz; found_hdr = true; } } Modified: libunwind/trunk/src/UnwindCursor.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindCursor.hpp?rev=297149&r1=297148&r2=297149&view=diff == --- libunwind/trunk/src/UnwindCursor.hpp (original) +++ libunwind/trunk/src/UnwindCursor.hpp Tue Mar 7 09:21:57 2017 @@ -693,7 +693,8 @@ struct EHABISectionIterator { return _Self(addressSpace, sects, 0); } static _Self end(A& addressSpace, const UnwindInfoSections& sects) { -return _Self(addressSpace, sects, sects.arm_section_length); +return _Self(addressSpace, sects, + sects.arm_section_length / sizeof(EHABIIndexEntry)); } EHABISectionIterator(A& addressSpace, const UnwindInfoSections& sects, size_t i) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28445: [Analyzer] Extend taint propagation and checking
NoQ accepted this revision. NoQ added a comment. This revision is now accepted and ready to land. I believe this should land. Thank you very much for getting this far to get this fixed. My take on the documentation: Return the default value bound to a region in a given store. The default binding is the value of sub-regions that were not initialized separately from their base region. For example, if the structure is zero-initialized upon construction, this method retrieves the concrete zero value, even if some or all fields were later overwritten manually. Default binding may be an unknown, undefined, concrete, or symbolic value. \param[in] store The store in which to make the lookup. \param[in] R The region to find the default binding for. Return the default value bound to a LazyCompoundVal. The default binding is used to represent the value of any fields or elements within the structure represented by the LazyCompoundVal which were not initialized explicitly separately from the whole structure. Default binding may be an unknown, undefined, concrete, or symbolic value. \param[in] lcv The lazy compound value. \return The default value bound to the LazyCompoundVal \c lcv, if a default binding exists. Comment at: lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp:455 + // Otherwise, return a nullptr as there's not yet a functional way to taint + // sub-regions of LCVs. + return nullptr; I'm not sure if i mentioned this before, but for this case we could store taint information in the program state as a map **//T//** from symbols to sets of regions, so that a `SymbolDerived`-class symbol with parent symbol **//S//** and parent region **//R//** is auto-tainted when **//R//** is a sub-region of at least one region **//R'//** in **//T(S)//**. That is, if we need to taint some fields in a structure with default symbol **//S//**, we add the relevant field regions to **//T(S)//**, and later lookup if the derived symbol's parent region is within one of the "tainted-regions-for-that-symbol". That's a crazy plan, but i believe it's also quite expressive, using the SVal hierarchy to the fullest. So it might be the way to go. https://reviews.llvm.org/D28445 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: r297140 - [clang-format] Support namespaces ending in semicolon
Looks to be failing existing tests? FAIL: Clang-Unit :: Format/FormatTests/FormatTest.BreaksLongDeclarations (12427 of 32080) TEST 'Clang-Unit :: Format/FormatTests/FormatTest.BreaksLongDeclarations' FAILED Note: Google Test filter = FormatTest.BreaksLongDeclarations [==] Running 1 test from 1 test case. [--] Global test environment set-up. [--] 1 test from FormatTest [ RUN ] FormatTest.BreaksLongDeclarations /usr/local/google/home/blaikie/dev/llvm/src/tools/clang/unittests/Format/FormatTest.cpp:73: Failure Expected: Code.str() Which is: "template // Templates on own line.\nstatic int // Some comment.\nMyFunction(int a);" To be equal to: format(test::messUp(Code), Style) Which is: "template // Templates on own line.\nstatic int// Some comment.\nMyFunction(int a);" With diff: @@ -1,3 +1,3 @@ -template // Templates on own line. -static int // Some comment. +template // Templates on own line. +static int// Some comment. MyFunction(int a); /usr/local/google/home/blaikie/dev/llvm/src/tools/clang/unittests/Format/FormatTest.cpp:79: Failure Expected: Code.str() Which is: "template // Templates on own line.\nstatic int // Some comment.\nMyFunction(int a);" To be equal to: format(test::messUp(Code), ObjCStyle) Which is: "template // Templates on own line.\nstatic int// Some comment.\nMyFunction(int a);" With diff: @@ -1,3 +1,3 @@ -template // Templates on own line. -static int // Some comment. +template // Templates on own line. +static int// Some comment. MyFunction(int a); On Tue, Mar 7, 2017 at 6:19 AM Krasimir Georgiev via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: krasimir > Date: Tue Mar 7 08:07:43 2017 > New Revision: 297140 > > URL: http://llvm.org/viewvc/llvm-project?rev=297140&view=rev > Log: > [clang-format] Support namespaces ending in semicolon > > Summary: > This patch adds support for namespaces ending in semicolon to the > namespace comment fixer. > source: > ``` > namespace A { > int i; > int j; > }; > ``` > clang-format before: > ``` > namespace A { > int i; > int j; > } // namespace A; > ``` > clang-format after: > ``` > namespace A { > int i; > int j; > }; // namespace A > ``` > > Reviewers: djasper > > Reviewed By: djasper > > Subscribers: cfe-commits, klimek > > Differential Revision: https://reviews.llvm.org/D30688 > > 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=297140&r1=297139&r2=297140&view=diff > > == > --- cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp (original) > +++ cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp Tue Mar 7 08:07:43 > 2017 > @@ -139,20 +139,34 @@ tooling::Replacements NamespaceEndCommen > if (RBraceTok->Finalized) >continue; > RBraceTok->Finalized = true; > +const FormatToken *EndCommentPrevTok = RBraceTok; > +// Namespaces often end with '};'. In that case, attach namespace end > +// comments to the semicolon tokens. > +if (RBraceTok->Next && RBraceTok->Next->is(tok::semi)) { > + EndCommentPrevTok = RBraceTok->Next; > +} > +// The next token in the token stream after the place where the end > comment > +// token must be. This is either the next token on the current line > or the > +// first token on the next line. > +const FormatToken *EndCommentNextTok = EndCommentPrevTok->Next; > +if (EndCommentNextTok && EndCommentNextTok->is(tok::comment)) > + EndCommentNextTok = EndCommentNextTok->Next; > +if (!EndCommentNextTok && I + 1 < E) > + EndCommentNextTok = AnnotatedLines[I + 1]->First; > +bool AddNewline = EndCommentNextTok && > + EndCommentNextTok->NewlinesBefore == 0 && > + EndCommentNextTok->isNot(tok::eof); > const std::string NamespaceName = computeName(NamespaceTok); > -bool AddNewline = (I + 1 < E) && > - AnnotatedLines[I + 1]->First->NewlinesBefore == 0 && > - AnnotatedLines[I + 1]->First->isNot(tok::eof); > const std::string EndCommentText = > computeEndCommentText(NamespaceName, AddNewline); > -if (!hasEndComment(RBraceTok)) { > +if (!hasEndComment(EndCommentPrevTok)) { >bool isShort = I - StartLineIndex <= kShortNamespaceMaxLines + 1; >if (!isShort) > -addEndComment(RBraceTok, EndCommentText, SourceMgr, &Fixes); > +addEndComment(EndCommentPrevTok, EndCommentText, SourceMgr, > &Fixes); >continue; > } > -if (!validEndComment(RBraceTok, NamespaceName)) > -
[PATCH] D30489: [analyzer] catch out of bounds for VLA
danielmarjamaki added a comment. > Also, in your state dumps no information is actually lost. The fact that the > value of variable sz is reg_$0 is trivial: you could ask the Store what's > the value of the variable sz and it'd say reg_$0 if there are no bindings > over it. Thanks. I have tried to dig around in the framework. I don't see how I can get it. I also don't want to get the "current" symbolvalue for the variable. For example: void f(int X) { int Buf[X]; X--; Buf[X] = 0; } So I envision that I need to tell the Store which "X" I want. I am trying to get the "X" symbol that defines the VLA size. > If no, an alternative approach would be to properly set the constraints on > the extent of the VLA's memory region. For information I tried to set the extent for the VLA.. by copy/pasting some code from the other diff. Ideally I don't think it should be set in checkPreStmt but this was an experiment... void ArrayBoundCheckerV2::checkPreStmt(const ArraySubscriptExpr *A, CheckerContext &C) const { ASTContext &Ctx = C.getASTContext(); QualType T = A->getBase()->IgnoreCasts()->getType(); const VariableArrayType *VLA = Ctx.getAsVariableArrayType(T); if (!VLA) return; ProgramStateRef State = C.getState(); SVal ElementCount = State->getSVal(VLA->getSizeExpr(), C.getLocationContext()); QualType ElementType = VLA->getElementType(); ASTContext &AstContext = C.getASTContext(); CharUnits TypeSize = AstContext.getTypeSizeInChars(ElementType); if (Optional DefinedSize = ElementCount.getAs()) { SVal AV = State->getSVal(A->getBase(), C.getLocationContext()); const SubRegion *Region = AV.getAsRegion()->getAs(); SValBuilder &svalBuilder = C.getSValBuilder(); DefinedOrUnknownSVal Extent = Region->getExtent(svalBuilder); // size in Bytes = ElementCount*TypeSize SVal SizeInBytes = svalBuilder.evalBinOpNN( State, BO_Mul, ElementCount.castAs(), svalBuilder.makeArrayIndex(TypeSize.getQuantity()), svalBuilder.getArrayIndexType()); DefinedOrUnknownSVal extentMatchesSize = svalBuilder.evalEQ( State, Extent, SizeInBytes.castAs()); State = State->assume(extentMatchesSize, true); C.addTransition(State); } } After this the ArrayBoundCheckerV2 still doesn't catch the bugs. As far as I could see that made very little difference. To me the extentValue looks the same. > If not it's possible that we are hitting the Constraint Solver limitations. Yes. I was hoping that I would be able to update SimpleSValBuilder::evalBinOpNN() somehow. And first I wanted to see if I could do it in the checker where all the CheckerContext and stuff is available. Repository: rL LLVM https://reviews.llvm.org/D30489 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297153 - [analyzer] Improve valist checks and move it out from alpha state.
Author: xazax Date: Tue Mar 7 10:04:23 2017 New Revision: 297153 URL: http://llvm.org/viewvc/llvm-project?rev=297153&view=rev Log: [analyzer] Improve valist checks and move it out from alpha state. This patch makes the valist check more robust to the different AST variants on different platforms and also fixes a FIXME. Differential Revision: https://reviews.llvm.org/D30157 Added: cfe/trunk/test/Analysis/valist-uninitialized-no-undef.c Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp cfe/trunk/test/Analysis/valist-uninitialized.c cfe/trunk/test/Analysis/valist-unterminated.c Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=297153&r1=297152&r2=297153&view=diff == --- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original) +++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Tue Mar 7 10:04:23 2017 @@ -45,7 +45,6 @@ def CplusplusAlpha : Package<"cplusplus" def CplusplusOptIn : Package<"cplusplus">, InPackage; def Valist : Package<"valist">; -def ValistAlpha : Package<"valist">, InPackage, Hidden; def DeadCode : Package<"deadcode">; def DeadCodeAlpha : Package<"deadcode">, InPackage, Hidden; @@ -291,7 +290,7 @@ def IteratorPastEndChecker : Checker<"It // Valist checkers. //===--===// -let ParentPackage = ValistAlpha in { +let ParentPackage = Valist in { def UninitializedChecker : Checker<"Uninitialized">, HelpText<"Check for usages of uninitialized (or already released) va_lists.">, @@ -305,7 +304,7 @@ def CopyToSelfChecker : Checker<"CopyToS HelpText<"Check for va_lists which are copied onto itself.">, DescFile<"ValistChecker.cpp">; -} // end : "alpha.valist" +} // end : "valist" //===--===// // Deadcode checkers. Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp?rev=297153&r1=297152&r2=297153&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp Tue Mar 7 10:04:23 2017 @@ -54,11 +54,11 @@ public: void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const; private: - const MemRegion *getVAListAsRegion(SVal SV, CheckerContext &C) const; + const MemRegion *getVAListAsRegion(SVal SV, const Expr *VAExpr, + bool &IsSymbolic, CheckerContext &C) const; StringRef getVariableNameFromRegion(const MemRegion *Reg) const; const ExplodedNode *getStartCallSite(const ExplodedNode *N, - const MemRegion *Reg, - CheckerContext &C) const; + const MemRegion *Reg) const; void reportUninitializedAccess(const MemRegion *VAList, StringRef Msg, CheckerContext &C) const; @@ -138,14 +138,21 @@ void ValistChecker::checkPreCall(const C for (auto FuncInfo : VAListAccepters) { if (!Call.isCalled(FuncInfo.Func)) continue; + bool Symbolic; const MemRegion *VAList = - getVAListAsRegion(Call.getArgSVal(FuncInfo.VAListPos), C); + getVAListAsRegion(Call.getArgSVal(FuncInfo.VAListPos), +Call.getArgExpr(FuncInfo.VAListPos), Symbolic, C); if (!VAList) return; if (C.getState()->contains(VAList)) return; + // We did not see va_start call, but the source of the region is unknown. + // Be conservative and assume the best. + if (Symbolic) +return; + SmallString<80> Errmsg("Function '"); Errmsg += FuncInfo.Func.getFunctionName(); Errmsg += "' is called with an uninitialized va_list argument"; @@ -155,13 +162,45 @@ void ValistChecker::checkPreCall(const C } } +const MemRegion *ValistChecker::getVAListAsRegion(SVal SV, const Expr *E, + bool &IsSymbolic, + CheckerContext &C) const { + // FIXME: on some platforms CallAndMessage checker finds some instances of + // the uninitialized va_list usages. CallAndMessage checker is disabled in + // the tests so they can verify platform independently those issues. As a + // side effect, this check is required here. + if (SV.isUnknownOrUndef()) +return nullptr; + // TODO: In the future this should be abstracted away by the analyzer. + bool VaListModelledAsArray = false; + i
[PATCH] D30157: [analyzer] Improve valist check
This revision was automatically updated to reflect the committed changes. Closed by commit rL297153: [analyzer] Improve valist checks and move it out from alpha state. (authored by xazax). Changed prior to commit: https://reviews.llvm.org/D30157?vs=90676&id=90855#toc Repository: rL LLVM https://reviews.llvm.org/D30157 Files: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp cfe/trunk/test/Analysis/valist-uninitialized-no-undef.c cfe/trunk/test/Analysis/valist-uninitialized.c cfe/trunk/test/Analysis/valist-unterminated.c Index: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td === --- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -45,7 +45,6 @@ def CplusplusOptIn : Package<"cplusplus">, InPackage; def Valist : Package<"valist">; -def ValistAlpha : Package<"valist">, InPackage, Hidden; def DeadCode : Package<"deadcode">; def DeadCodeAlpha : Package<"deadcode">, InPackage, Hidden; @@ -291,7 +290,7 @@ // Valist checkers. //===--===// -let ParentPackage = ValistAlpha in { +let ParentPackage = Valist in { def UninitializedChecker : Checker<"Uninitialized">, HelpText<"Check for usages of uninitialized (or already released) va_lists.">, @@ -305,7 +304,7 @@ HelpText<"Check for va_lists which are copied onto itself.">, DescFile<"ValistChecker.cpp">; -} // end : "alpha.valist" +} // end : "valist" //===--===// // Deadcode checkers. Index: cfe/trunk/test/Analysis/valist-unterminated.c === --- cfe/trunk/test/Analysis/valist-unterminated.c +++ cfe/trunk/test/Analysis/valist-unterminated.c @@ -1,49 +1,56 @@ -// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,alpha.valist.Unterminated,alpha.valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s +// RUN: %clang_analyze_cc1 -triple hexagon-unknown-linux -analyzer-checker=core,valist.Unterminated,valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s +// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,valist.Unterminated,valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s #include "Inputs/system-header-simulator-for-valist.h" void f1(int fst, ...) { va_list va; va_start(va, fst); // expected-note{{Initialized va_list}} - return; // expected-warning{{Initialized va_list 'va' is leaked}} expected-note{{Initialized va_list 'va' is leaked}} + return; // expected-warning{{Initialized va_list 'va' is leaked}} + // expected-note@-1{{Initialized va_list 'va' is leaked}} } void f2(int fst, ...) { va_list va; va_start(va, fst); // expected-note{{Initialized va_list}} va_end(va); // expected-note{{Ended va_list}} va_start(va, fst); // expected-note{{Initialized va_list}} -} // expected-warning{{Initialized va_list 'va' is leaked}} expected-note{{Initialized va_list 'va' is leaked}}} +} // expected-warning{{Initialized va_list 'va' is leaked}} + // expected-note@-1{{Initialized va_list 'va' is leaked}} void f3(int fst, ...) { va_list va, va2; va_start(va, fst); va_copy(va2, va); // expected-note{{Initialized va_list}} - va_end(va); // expected-warning{{Initialized va_list 'va2' is leaked}} expected-note{{Initialized va_list 'va2' is leaked}} + va_end(va); // expected-warning{{Initialized va_list 'va2' is leaked}} + // expected-note@-1{{Initialized va_list 'va2' is leaked}} } void f4(va_list *fst, ...) { va_start(*fst, fst); // expected-note{{Initialized va_list}} - return; // expected-warning{{Initialized va_list is leaked}} expected-note{{Initialized va_list is leaked}} + return; // expected-warning{{Initialized va_list is leaked}} + // expected-note@-1{{Initialized va_list is leaked}} } void f5(va_list fst, ...) { - va_start(fst, fst); - //FIXME: this should cause a warning -} // no-warning + va_start(fst, fst); // expected-note{{Initialized va_list}} +} // expected-warning{{Initialized va_list}} + // expected-note@-1{{Initialized va_list}} void f6(va_list *fst, ...) { va_start(*fst, fst); // expected-note{{Initialized va_list}} (void)va_arg(*fst, int); //FIXME: this should NOT cause a warning - va_end(*fst); // expected-warning{{Initialized va_list is leaked}} expected-note{{Initialized va_list is leaked}} + va_end(*fst); // expected-warning{{Initialized va_list is leaked}} + // expected-note@-1{{Initialized va_list is leaked}} } void f7(int *fst, ...) { va_list x; va_list *y = &x; va_start(*y,fst); // expected-note{{Initialized va_list}} -} // expected-warning{{Initialized va_list 'x' is leaked}} expected-note{{Initia
[PATCH] D30697: [clang-format] Enable comment reflowing in multiline comments containing pragmas
krasimir created this revision. Herald added a subscriber: klimek. This patch enables comment reflowing of lines not matching the comment pragma regex in multiline comments containing comment pragma lines. Previously, these comments were dumped without being reindented to the result. https://reviews.llvm.org/D30697 Files: lib/Format/BreakableToken.cpp lib/Format/BreakableToken.h lib/Format/ContinuationIndenter.cpp unittests/Format/FormatTestJS.cpp Index: unittests/Format/FormatTestJS.cpp === --- unittests/Format/FormatTestJS.cpp +++ unittests/Format/FormatTestJS.cpp @@ -1607,6 +1607,27 @@ " * @param This is a long comment but no type\n" " */", getGoogleJSStyleWithColumns(20)); + // Don't break @param line, but reindent unrelated lines. + verifyFormat("{\n" + " /**\n" + " * long long long\n" + " * long\n" + " * @param {this.is.a.long.path.to.a.Type}\n" + " * long long long\n" + " * long long\n" + " */\n" + " function f(a) {}\n" + "}", + "{\n" + "/**\n" + " * long long long long\n" + " * @param {this.is.a.long.path.to.a.Type}\n" + " * long long long long\n" + " * long\n" + " */\n" + " function f(a) {}\n" + "}", + getGoogleJSStyleWithColumns(20)); } TEST_F(FormatTestJS, RequoteStringsSingle) { @@ -1695,6 +1716,5 @@ getGoogleJSStyleWithColumns(25)); verifyFormat("// taze: x from 'location'", getGoogleJSStyleWithColumns(10)); } - } // end namespace tooling } // end namespace clang Index: lib/Format/ContinuationIndenter.cpp === --- lib/Format/ContinuationIndenter.cpp +++ lib/Format/ContinuationIndenter.cpp @@ -1183,7 +1183,6 @@ } } else if (Current.is(TT_BlockComment)) { if (!Current.isTrailingComment() || !Style.ReflowComments || -CommentPragmasRegex.match(Current.TokenText.substr(2)) || // If a comment token switches formatting, like // /* clang-format on */, we don't want to break it further, // but we may still want to adjust its indentation. @@ -1234,8 +1233,8 @@ RemainingTokenColumns = Token->getLineLengthAfterSplitBefore( LineIndex, TailOffset, RemainingTokenColumns, ColumnLimit, SplitBefore); while (RemainingTokenColumns > RemainingSpace) { - BreakableToken::Split Split = - Token->getSplit(LineIndex, TailOffset, ColumnLimit); + BreakableToken::Split Split = Token->getSplit( + LineIndex, TailOffset, ColumnLimit, CommentPragmasRegex); if (Split.first == StringRef::npos) { // The last line's penalty is handled in addNextStateToQueue(). if (LineIndex < EndIndex - 1) Index: lib/Format/BreakableToken.h === --- lib/Format/BreakableToken.h +++ lib/Format/BreakableToken.h @@ -90,7 +90,8 @@ /// \p LineIndex, if previously broken at \p TailOffset. If possible, do not /// violate \p ColumnLimit. virtual Split getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const = 0; + unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const = 0; /// \brief Emits the previously retrieved \p Split via \p Whitespaces. virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split, @@ -198,8 +199,8 @@ bool InPPDirective, encoding::Encoding Encoding, const FormatStyle &Style); - Split getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const override; + Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const override; void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split, WhitespaceManager &Whitespaces) override; void compressWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split, @@ -218,8 +219,8 @@ public: unsigned getLineCount() const override; - Split getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const override; + Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const override; void compressWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split, WhitespaceManager &Whitespaces) override; Index: lib/Format/BreakableToken.cpp === --- lib/Format/BreakableToken.cpp +++ lib/Format/BreakableToken.cpp @@ -20
[PATCH] D30697: [clang-format] Enable comment reflowing in multiline comments containing pragmas
krasimir updated this revision to Diff 90859. krasimir added a comment. - Fix test comment https://reviews.llvm.org/D30697 Files: lib/Format/BreakableToken.cpp lib/Format/BreakableToken.h lib/Format/ContinuationIndenter.cpp unittests/Format/FormatTestJS.cpp Index: unittests/Format/FormatTestJS.cpp === --- unittests/Format/FormatTestJS.cpp +++ unittests/Format/FormatTestJS.cpp @@ -1607,6 +1607,27 @@ " * @param This is a long comment but no type\n" " */", getGoogleJSStyleWithColumns(20)); + // Don't break @param line, but reindent it and reflow unrelated lines. + verifyFormat("{\n" + " /**\n" + " * long long long\n" + " * long\n" + " * @param {this.is.a.long.path.to.a.Type}\n" + " * long long long\n" + " * long long\n" + " */\n" + " function f(a) {}\n" + "}", + "{\n" + "/**\n" + " * long long long long\n" + " * @param {this.is.a.long.path.to.a.Type}\n" + " * long long long long\n" + " * long\n" + " */\n" + " function f(a) {}\n" + "}", + getGoogleJSStyleWithColumns(20)); } TEST_F(FormatTestJS, RequoteStringsSingle) { @@ -1695,6 +1716,5 @@ getGoogleJSStyleWithColumns(25)); verifyFormat("// taze: x from 'location'", getGoogleJSStyleWithColumns(10)); } - } // end namespace tooling } // end namespace clang Index: lib/Format/ContinuationIndenter.cpp === --- lib/Format/ContinuationIndenter.cpp +++ lib/Format/ContinuationIndenter.cpp @@ -1183,7 +1183,6 @@ } } else if (Current.is(TT_BlockComment)) { if (!Current.isTrailingComment() || !Style.ReflowComments || -CommentPragmasRegex.match(Current.TokenText.substr(2)) || // If a comment token switches formatting, like // /* clang-format on */, we don't want to break it further, // but we may still want to adjust its indentation. @@ -1234,8 +1233,8 @@ RemainingTokenColumns = Token->getLineLengthAfterSplitBefore( LineIndex, TailOffset, RemainingTokenColumns, ColumnLimit, SplitBefore); while (RemainingTokenColumns > RemainingSpace) { - BreakableToken::Split Split = - Token->getSplit(LineIndex, TailOffset, ColumnLimit); + BreakableToken::Split Split = Token->getSplit( + LineIndex, TailOffset, ColumnLimit, CommentPragmasRegex); if (Split.first == StringRef::npos) { // The last line's penalty is handled in addNextStateToQueue(). if (LineIndex < EndIndex - 1) Index: lib/Format/BreakableToken.h === --- lib/Format/BreakableToken.h +++ lib/Format/BreakableToken.h @@ -90,7 +90,8 @@ /// \p LineIndex, if previously broken at \p TailOffset. If possible, do not /// violate \p ColumnLimit. virtual Split getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const = 0; + unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const = 0; /// \brief Emits the previously retrieved \p Split via \p Whitespaces. virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split, @@ -198,8 +199,8 @@ bool InPPDirective, encoding::Encoding Encoding, const FormatStyle &Style); - Split getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const override; + Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const override; void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split, WhitespaceManager &Whitespaces) override; void compressWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split, @@ -218,8 +219,8 @@ public: unsigned getLineCount() const override; - Split getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const override; + Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const override; void compressWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split, WhitespaceManager &Whitespaces) override; Index: lib/Format/BreakableToken.cpp === --- lib/Format/BreakableToken.cpp +++ lib/Format/BreakableToken.cpp @@ -200,7 +200,8 @@ BreakableToken::Split BreakableStringLiteral::getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const { +
[PATCH] D26316: [coroutines] Build and pass coroutine_handle to await_suspend.
GorNishanov updated this revision to Diff 90861. GorNishanov added a comment. Per's @rsmith feedback in Kona - Added diagnostic if from_address is missing from coroutine_handle - Switch to using BuildDeclarationNameExpr in buildCoroutineHandle https://reviews.llvm.org/D26316 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaCoroutine.cpp lib/Sema/SemaExprMember.cpp test/CodeGenCoroutines/coro-alloc.cpp test/CodeGenCoroutines/coro-return.cpp test/SemaCXX/coroutines.cpp Index: test/SemaCXX/coroutines.cpp === --- test/SemaCXX/coroutines.cpp +++ test/SemaCXX/coroutines.cpp @@ -16,42 +16,52 @@ // expected-error@-1 {{use of undeclared identifier 'a'}} } +void no_coroutine_traits() { + co_await 4; // expected-error {{need to include }} +} + +namespace std { +namespace experimental { +template +struct coroutine_traits; // expected-note {{declared here}} + +template +struct coroutine_handle { + static coroutine_handle from_address(void *); +}; + +template <> +struct coroutine_handle { + template + coroutine_handle(coroutine_handle); + static coroutine_handle from_address(void *); +}; +}} // namespace std::experimental + +template struct coro {}; +template +struct std::experimental::coroutine_traits, Ps...> { + using promise_type = Promise; +}; struct awaitable { bool await_ready(); - void await_suspend(); // FIXME: coroutine_handle + void await_suspend(std::experimental::coroutine_handle<>); void await_resume(); } a; struct suspend_always { bool await_ready() { return false; } - void await_suspend() {} + void await_suspend(std::experimental::coroutine_handle<>) {} void await_resume() {} }; struct suspend_never { bool await_ready() { return true; } - void await_suspend() {} + void await_suspend(std::experimental::coroutine_handle<>) {} void await_resume() {} }; -void no_coroutine_traits() { - co_await a; // expected-error {{need to include }} -} - -namespace std { -namespace experimental { -template -struct coroutine_traits; // expected-note {{declared here}} -} -} - -template struct coro {}; -template -struct std::experimental::coroutine_traits, Ps...> { - using promise_type = Promise; -}; - void no_specialization() { co_await a; // expected-error {{implicit instantiation of undefined template 'std::experimental::coroutine_traits'}} } @@ -86,13 +96,6 @@ struct std::experimental::coroutine_traits { using promise_type = promise_void; }; -namespace std { -namespace experimental { -template -struct coroutine_handle; -} -} - // FIXME: This diagnostic is terrible. void undefined_promise() { // expected-error {{this function cannot be a coroutine: 'experimental::coroutine_traits::promise_type' (aka 'promise') is an incomplete type}} co_await a; @@ -520,3 +523,20 @@ int main(int, const char**) { co_await a; // expected-error {{'co_await' cannot be used in the 'main' function}} } + +struct good_promise_2 { + float get_return_object(); + suspend_always initial_suspend(); + suspend_always final_suspend(); + void return_void(); +}; +template<> struct std::experimental::coroutine_handle {}; + +template<> struct std::experimental::coroutine_traits +{ using promise_type = good_promise_2; }; + +float badly_specialized_coro_handle() { // expected-error {{std::experimental::coroutine_handle missing a member named 'from_address'}} + //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}} + //expected-note@+1 {{function is a coroutine due to use of 'co_return' here}} + co_return; +} Index: test/CodeGenCoroutines/coro-return.cpp === --- test/CodeGenCoroutines/coro-return.cpp +++ test/CodeGenCoroutines/coro-return.cpp @@ -4,12 +4,27 @@ namespace experimental { template struct coroutine_traits; + +template +struct coroutine_handle { + coroutine_handle() = default; + static coroutine_handle from_address(void *) { return {}; } +}; + +template <> +struct coroutine_handle { + static coroutine_handle from_address(void *) { return {}; } + coroutine_handle() = default; + template + coroutine_handle(coroutine_handle) {} +}; + } } struct suspend_always { bool await_ready(); - void await_suspend(); + void await_suspend(std::experimental::coroutine_handle<>); void await_resume(); }; Index: test/CodeGenCoroutines/coro-alloc.cpp === --- test/CodeGenCoroutines/coro-alloc.cpp +++ test/CodeGenCoroutines/coro-alloc.cpp @@ -4,12 +4,27 @@ namespace experimental { template struct coroutine_traits; // expected-note {{declared here}} + +template +struct coroutine_handle { + coroutine_handle() = default; + static coroutine_handle from_address(void *) { return {}; } +}; + +template <> +struct coroutine_handle { + static coroutine_handle from_address(void *) { return {}; } + corouti
[PATCH] D26316: [coroutines] Build and pass coroutine_handle to await_suspend.
GorNishanov updated this revision to Diff 90862. GorNishanov added a comment. - removed '&' that snicked near Location parameter - reordered a few lines to minimize the diff from Eric's version https://reviews.llvm.org/D26316 Files: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaCoroutine.cpp lib/Sema/SemaExprMember.cpp test/CodeGenCoroutines/coro-alloc.cpp test/CodeGenCoroutines/coro-return.cpp test/SemaCXX/coroutines.cpp Index: test/SemaCXX/coroutines.cpp === --- test/SemaCXX/coroutines.cpp +++ test/SemaCXX/coroutines.cpp @@ -16,42 +16,52 @@ // expected-error@-1 {{use of undeclared identifier 'a'}} } +void no_coroutine_traits() { + co_await 4; // expected-error {{need to include }} +} + +namespace std { +namespace experimental { +template +struct coroutine_traits; // expected-note {{declared here}} + +template +struct coroutine_handle { + static coroutine_handle from_address(void *); +}; + +template <> +struct coroutine_handle { + template + coroutine_handle(coroutine_handle); + static coroutine_handle from_address(void *); +}; +}} // namespace std::experimental + +template struct coro {}; +template +struct std::experimental::coroutine_traits, Ps...> { + using promise_type = Promise; +}; struct awaitable { bool await_ready(); - void await_suspend(); // FIXME: coroutine_handle + void await_suspend(std::experimental::coroutine_handle<>); void await_resume(); } a; struct suspend_always { bool await_ready() { return false; } - void await_suspend() {} + void await_suspend(std::experimental::coroutine_handle<>) {} void await_resume() {} }; struct suspend_never { bool await_ready() { return true; } - void await_suspend() {} + void await_suspend(std::experimental::coroutine_handle<>) {} void await_resume() {} }; -void no_coroutine_traits() { - co_await a; // expected-error {{need to include }} -} - -namespace std { -namespace experimental { -template -struct coroutine_traits; // expected-note {{declared here}} -} -} - -template struct coro {}; -template -struct std::experimental::coroutine_traits, Ps...> { - using promise_type = Promise; -}; - void no_specialization() { co_await a; // expected-error {{implicit instantiation of undefined template 'std::experimental::coroutine_traits'}} } @@ -86,13 +96,6 @@ struct std::experimental::coroutine_traits { using promise_type = promise_void; }; -namespace std { -namespace experimental { -template -struct coroutine_handle; -} -} - // FIXME: This diagnostic is terrible. void undefined_promise() { // expected-error {{this function cannot be a coroutine: 'experimental::coroutine_traits::promise_type' (aka 'promise') is an incomplete type}} co_await a; @@ -520,3 +523,20 @@ int main(int, const char**) { co_await a; // expected-error {{'co_await' cannot be used in the 'main' function}} } + +struct good_promise_2 { + float get_return_object(); + suspend_always initial_suspend(); + suspend_always final_suspend(); + void return_void(); +}; +template<> struct std::experimental::coroutine_handle {}; + +template<> struct std::experimental::coroutine_traits +{ using promise_type = good_promise_2; }; + +float badly_specialized_coro_handle() { // expected-error {{std::experimental::coroutine_handle missing a member named 'from_address'}} + //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}} + //expected-note@+1 {{function is a coroutine due to use of 'co_return' here}} + co_return; +} Index: test/CodeGenCoroutines/coro-return.cpp === --- test/CodeGenCoroutines/coro-return.cpp +++ test/CodeGenCoroutines/coro-return.cpp @@ -4,12 +4,27 @@ namespace experimental { template struct coroutine_traits; + +template +struct coroutine_handle { + coroutine_handle() = default; + static coroutine_handle from_address(void *) { return {}; } +}; + +template <> +struct coroutine_handle { + static coroutine_handle from_address(void *) { return {}; } + coroutine_handle() = default; + template + coroutine_handle(coroutine_handle) {} +}; + } } struct suspend_always { bool await_ready(); - void await_suspend(); + void await_suspend(std::experimental::coroutine_handle<>); void await_resume(); }; Index: test/CodeGenCoroutines/coro-alloc.cpp === --- test/CodeGenCoroutines/coro-alloc.cpp +++ test/CodeGenCoroutines/coro-alloc.cpp @@ -4,12 +4,27 @@ namespace experimental { template struct coroutine_traits; // expected-note {{declared here}} + +template +struct coroutine_handle { + coroutine_handle() = default; + static coroutine_handle from_address(void *) { return {}; } +}; + +template <> +struct coroutine_handle { + static coroutine_handle from_address(void *) { return {}; } + coroutine_handle() = default; + template + coroutine_ha
[PATCH] D30697: [clang-format] Enable comment reflowing in multiline comments containing pragmas
mprobst accepted this revision. mprobst added a comment. This revision is now accepted and ready to land. LGTM. https://reviews.llvm.org/D30697 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30691: [analyzer] Support for naive cross translational unit analysis
xazax.hun added a comment. Guide to run the two pass analysis: Process --- These are the steps of XTU analysis: 1. `xtu-build.py` script uses your compilation database and extracts all necessary information from files compiled. It puts all its generated data into a folder (.xtu by default). 2. `xtu-analyze.py` script uses all previously generated data and executes the analysis. It needs the clang binary and scan-build-py's analyze-cc in order to do that. The output is put into a folder (.xtu-out by default) where both the analysis reports and the called commands' generated output are stored. Usage example - 1. You have generated a compilation database and you are in your project's build directory 2. `xtu-build.py -b build.json -v --clang-path ` 3. `xtu-analyse.py -b build.json -v --clang-path --analyze-cc-path ` Repository: rL LLVM https://reviews.llvm.org/D30691 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30697: [clang-format] Enable comment reflowing in multiline comments containing pragmas
krasimir updated this revision to Diff 90864. krasimir added a comment. - Make the test example idiomatic https://reviews.llvm.org/D30697 Files: lib/Format/BreakableToken.cpp lib/Format/BreakableToken.h lib/Format/ContinuationIndenter.cpp unittests/Format/FormatTestJS.cpp Index: unittests/Format/FormatTestJS.cpp === --- unittests/Format/FormatTestJS.cpp +++ unittests/Format/FormatTestJS.cpp @@ -1607,6 +1607,27 @@ " * @param This is a long comment but no type\n" " */", getGoogleJSStyleWithColumns(20)); + // Don't break @param line, but reindent it and reflow unrelated lines. + verifyFormat("{\n" + " /**\n" + " * long long long\n" + " * long\n" + " * @param {this.is.a.long.path.to.a.Type} a\n" + " * long long long\n" + " * long long\n" + " */\n" + " function f(a) {}\n" + "}", + "{\n" + "/**\n" + " * long long long long\n" + " * @param {this.is.a.long.path.to.a.Type} a\n" + " * long long long long\n" + " * long\n" + " */\n" + " function f(a) {}\n" + "}", + getGoogleJSStyleWithColumns(20)); } TEST_F(FormatTestJS, RequoteStringsSingle) { @@ -1695,6 +1716,5 @@ getGoogleJSStyleWithColumns(25)); verifyFormat("// taze: x from 'location'", getGoogleJSStyleWithColumns(10)); } - } // end namespace tooling } // end namespace clang Index: lib/Format/ContinuationIndenter.cpp === --- lib/Format/ContinuationIndenter.cpp +++ lib/Format/ContinuationIndenter.cpp @@ -1183,7 +1183,6 @@ } } else if (Current.is(TT_BlockComment)) { if (!Current.isTrailingComment() || !Style.ReflowComments || -CommentPragmasRegex.match(Current.TokenText.substr(2)) || // If a comment token switches formatting, like // /* clang-format on */, we don't want to break it further, // but we may still want to adjust its indentation. @@ -1234,8 +1233,8 @@ RemainingTokenColumns = Token->getLineLengthAfterSplitBefore( LineIndex, TailOffset, RemainingTokenColumns, ColumnLimit, SplitBefore); while (RemainingTokenColumns > RemainingSpace) { - BreakableToken::Split Split = - Token->getSplit(LineIndex, TailOffset, ColumnLimit); + BreakableToken::Split Split = Token->getSplit( + LineIndex, TailOffset, ColumnLimit, CommentPragmasRegex); if (Split.first == StringRef::npos) { // The last line's penalty is handled in addNextStateToQueue(). if (LineIndex < EndIndex - 1) Index: lib/Format/BreakableToken.h === --- lib/Format/BreakableToken.h +++ lib/Format/BreakableToken.h @@ -90,7 +90,8 @@ /// \p LineIndex, if previously broken at \p TailOffset. If possible, do not /// violate \p ColumnLimit. virtual Split getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const = 0; + unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const = 0; /// \brief Emits the previously retrieved \p Split via \p Whitespaces. virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split, @@ -198,8 +199,8 @@ bool InPPDirective, encoding::Encoding Encoding, const FormatStyle &Style); - Split getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const override; + Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const override; void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split, WhitespaceManager &Whitespaces) override; void compressWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split, @@ -218,8 +219,8 @@ public: unsigned getLineCount() const override; - Split getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned ColumnLimit) const override; + Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit, + llvm::Regex &CommentPragmasRegex) const override; void compressWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split, WhitespaceManager &Whitespaces) override; Index: lib/Format/BreakableToken.cpp === --- lib/Format/BreakableToken.cpp +++ lib/Format/BreakableToken.cpp @@ -200,7 +200,8 @@ BreakableToken::Split BreakableStringLiteral::getSplit(unsigned LineIndex, unsigned TailOffset, - unsigned Column
[PATCH] D28445: [Analyzer] Extend taint propagation and checking
vlad.tsyrklevich updated this revision to Diff 90868. vlad.tsyrklevich added a comment. Updated with the documentation update from @NoQ https://reviews.llvm.org/D28445 Files: include/clang/StaticAnalyzer/Core/PathSensitive/Store.h lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp lib/StaticAnalyzer/Core/RegionStore.cpp test/Analysis/taint-generic.c Index: test/Analysis/taint-generic.c === --- test/Analysis/taint-generic.c +++ test/Analysis/taint-generic.c @@ -169,6 +169,43 @@ sock = socket(AF_LOCAL, SOCK_STREAM, 0); read(sock, buffer, 100); execl(buffer, "filename", 0); // no-warning + + sock = socket(AF_INET, SOCK_STREAM, 0); + // References to both buffer and &buffer as an argument should taint the argument + read(sock, &buffer, 100); + execl(buffer, "filename", 0); // expected-warning {{Untrusted data is passed to a system call}} +} + +void testStruct() { + struct { +char buf[16]; +int length; + } tainted; + + char buffer[16]; + int sock; + + sock = socket(AF_INET, SOCK_STREAM, 0); + read(sock, &tainted, sizeof(tainted)); + __builtin_memcpy(buffer, tainted.buf, tainted.length); // expected-warning {{Untrusted data is used to specify the buffer size}} +} + +void testStructArray() { + struct { +char buf[16]; +struct { + int length; +} st[1]; + } tainted; + + char buffer[16]; + int sock; + + sock = socket(AF_INET, SOCK_STREAM, 0); + read(sock, &tainted.buf[0], sizeof(tainted.buf)); + read(sock, &tainted.st[0], sizeof(tainted.st)); + // FIXME: tainted.st[0].length should be marked tainted + __builtin_memcpy(buffer, tainted.buf, tainted.st[0].length); // no-warning } int testDivByZero() { Index: lib/StaticAnalyzer/Core/RegionStore.cpp === --- lib/StaticAnalyzer/Core/RegionStore.cpp +++ lib/StaticAnalyzer/Core/RegionStore.cpp @@ -494,6 +494,11 @@ return getBinding(getRegionBindings(S), L, T); } + Optional getDefaultBinding(Store S, const MemRegion *R) override { +RegionBindingsRef B = getRegionBindings(S); +return B.getDefaultBinding(R); + } + SVal getBinding(RegionBindingsConstRef B, Loc L, QualType T = QualType()); SVal getBindingForElement(RegionBindingsConstRef B, const ElementRegion *R); Index: lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp === --- lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp +++ lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp @@ -65,6 +65,18 @@ /// and thus, is tainted. static bool isStdin(const Expr *E, CheckerContext &C); + /// This is called from getPointedToSymbol() to resolve symbol references for + /// the region underlying a LazyCompoundVal. This is the default binding + /// for the LCV, which could be a conjured symbol from a function call that + /// initialized the region. It only returns the conjured symbol if the LCV + /// covers the entire region, e.g. we avoid false positives by not returning + /// a default bindingc for an entire struct if the symbol for only a single + /// field or element within it is requested. + // TODO: Return an appropriate symbol for sub-fields/elements of an LCV so + // that they are also appropriately tainted. + static SymbolRef getLCVSymbol(CheckerContext &C, +nonloc::LazyCompoundVal &LCV); + /// \brief Given a pointer argument, get the symbol of the value it contains /// (points to). static SymbolRef getPointedToSymbol(CheckerContext &C, const Expr *Arg); @@ -423,6 +435,27 @@ return false; } +SymbolRef GenericTaintChecker::getLCVSymbol(CheckerContext &C, +nonloc::LazyCompoundVal &LCV) { + StoreManager &StoreMgr = C.getStoreManager(); + + // getLCVSymbol() is reached in a PostStmt so we can always expect a default + // binding to exist if one is present. + if (Optional binding = StoreMgr.getDefaultBinding(LCV)) { +SymbolRef Sym = binding->getAsSymbol(); +if (!Sym) + return nullptr; + +// If the LCV covers an entire base region return the default conjured symbol. +if (LCV.getRegion() == LCV.getRegion()->getBaseRegion()) + return Sym; + } + + // Otherwise, return a nullptr as there's not yet a functional way to taint + // sub-regions of LCVs. + return nullptr; +} + SymbolRef GenericTaintChecker::getPointedToSymbol(CheckerContext &C, const Expr* Arg) { ProgramStateRef State = C.getState(); @@ -438,6 +471,10 @@ dyn_cast(Arg->getType().getCanonicalType().getTypePtr()); SVal Val = State->getSVal(*AddrLoc, ArgTy ? ArgTy->getPointeeType(): QualType()); + + if (auto LCV = Val.getAs()) +return getLCVSymbol(C, *LCV); + return Val.getAsSymbol(); } Index: include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
[PATCH] D28445: [Analyzer] Extend taint propagation and checking
vlad.tsyrklevich added inline comments. Comment at: lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp:455 + // Otherwise, return a nullptr as there's not yet a functional way to taint + // sub-regions of LCVs. + return nullptr; NoQ wrote: > I'm not sure if i mentioned this before, but for this case we could store > taint information in the program state as a map **//T//** from symbols to > sets of regions, so that a `SymbolDerived`-class symbol with parent symbol > **//S//** and parent region **//R//** is auto-tainted when **//R//** is a > sub-region of at least one region **//R'//** in **//T(S)//**. > > That is, if we need to taint some fields in a structure with default symbol > **//S//**, we add the relevant field regions to **//T(S)//**, and later > lookup if the derived symbol's parent region is within one of the > "tainted-regions-for-that-symbol". > > That's a crazy plan, but i believe it's also quite expressive, using the SVal > hierarchy to the fullest. So it might be the way to go. That's exactly what I was considering, I can't imagine another clean way to keep track of that information otherwise (short of a linear scan of the taint data.) https://reviews.llvm.org/D28445 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297162 - Revert "Document that code inlined into a nodebug function also won't get any"
Author: adrian Date: Tue Mar 7 11:28:56 2017 New Revision: 297162 URL: http://llvm.org/viewvc/llvm-project?rev=297162&view=rev Log: Revert "Document that code inlined into a nodebug function also won't get any" This reverts commit r296776. This statement is no longer true. Modified: cfe/trunk/include/clang/Basic/AttrDocs.td Modified: cfe/trunk/include/clang/Basic/AttrDocs.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=297162&r1=297161&r2=297162&view=diff == --- cfe/trunk/include/clang/Basic/AttrDocs.td (original) +++ cfe/trunk/include/clang/Basic/AttrDocs.td Tue Mar 7 11:28:56 2017 @@ -657,8 +657,7 @@ def NoDebugDocs : Documentation { let Content = [{ The ``nodebug`` attribute allows you to suppress debugging information for a function or method, or for a variable that is not a parameter or a non-static -data member. It will also suppress debug information for any code that is -inlined into a ``nodebug`` function or method. +data member. }]; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30423: [ubsan] Detect UB loads from bitfields
vsk added a comment. In https://reviews.llvm.org/D30423#694003, @jroelofs wrote: > I think this might miss loads from bitfield ivars. I'll add a test that shows that this case is covered. > Also, what about the conversion that happens for properties whose backing > ivar is a bitfield? (or does that happen in the runtime? can't remember) I'll also check that synthesized getters have the range check. Comment at: test/CodeGenObjC/ubsan-bool.m:26 + // OBJC: [[ICMP:%.*]] = icmp ule i8 [[ASHR]], 1, !nosanitize + // OBJC: call void @__ubsan_handle_load_invalid_value + jroelofs wrote: > vsk wrote: > > arphaman wrote: > > > Is it possible to avoid the check here since the bitfield is just one bit > > > wide? > > No, a user could do: > > > > ``` > > struct S1 s; > > s.b1 = 1; > > if (s.b1 == 1) // evaluates to false, s.b1 is negative > > ``` > > > > With this patch we get: > > ``` > > runtime error: load of value -1, which is not a valid value for type 'BOOL' > > (aka 'signed char') > > ``` > What if BOOL is an `unsigned char`, or a `char` that's not signed? Good point, we don't need to emit the range check if the bitfield is an unsigned, 1-bit wide BOOL. Would you be OK with me tackling that in a follow-up patch? https://reviews.llvm.org/D30423 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30423: [ubsan] Detect UB loads from bitfields
vsk updated this revision to Diff 90869. vsk added a comment. - Improve objc test coverage per Jon's suggestions. https://reviews.llvm.org/D30423 Files: lib/CodeGen/CGAtomic.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CodeGenFunction.h test/CodeGenCXX/ubsan-bitfields.cpp test/CodeGenObjC/ubsan-bool.m Index: test/CodeGenObjC/ubsan-bool.m === --- test/CodeGenObjC/ubsan-bool.m +++ test/CodeGenObjC/ubsan-bool.m @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - | FileCheck %s -check-prefixes=SHARED,OBJC -// RUN: %clang_cc1 -x objective-c++ -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - | FileCheck %s -check-prefixes=SHARED,OBJC +// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - -w | FileCheck %s -check-prefixes=SHARED,OBJC +// RUN: %clang_cc1 -x objective-c++ -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - -w | FileCheck %s -check-prefixes=SHARED,OBJC // RUN: %clang_cc1 -x c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - | FileCheck %s -check-prefixes=SHARED,C typedef signed char BOOL; @@ -10,4 +10,57 @@ // C-NOT: call void @__ubsan_handle_load_invalid_value BOOL a = 2; return a + 1; + // SHARED: ret i8 } + +struct S1 { + BOOL b1 : 1; +}; + +// SHARED-LABEL: f2 +BOOL f2(struct S1 *s) { + // OBJC: [[LOAD:%.*]] = load i8, i8* {{.*}} + // OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7 + // OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7 + // OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize + // OBJC: call void @__ubsan_handle_load_invalid_value + + // C-NOT: call void @__ubsan_handle_load_invalid_value + return s->b1; + // SHARED: ret i8 +} + +#ifdef __OBJC__ +@interface I1 { +@public + BOOL b1 : 1; +} +@property (nonatomic) BOOL b1; +@end +@implementation I1 +@synthesize b1; +@end + +// Check the synthesized getter. +// OBJC-LABEL: define internal signext i8 @"\01-[I1 b1]" +// OBJC: [[IVAR:%.*]] = load i64, i64* @"OBJC_IVAR_$_I1.b1" +// OBJC: [[ADDR:%.*]] = getelementptr inbounds i8, i8* {{.*}}, i64 [[IVAR]] +// OBJC: [[LOAD:%.*]] = load i8, i8* {{.*}} +// OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7 +// OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7 +// OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize +// OBJC: call void @__ubsan_handle_load_invalid_value + +// Also check direct accesses to the ivar. +// OBJC-LABEL: f3 +BOOL f3(I1 *i) { + // OBJC: [[LOAD:%.*]] = load i8, i8* {{.*}} + // OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7 + // OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7 + // OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize + // OBJC: call void @__ubsan_handle_load_invalid_value + + return i->b1; + // OBJC: ret i8 +} +#endif /* __OBJC__ */ Index: test/CodeGenCXX/ubsan-bitfields.cpp === --- /dev/null +++ test/CodeGenCXX/ubsan-bitfields.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=enum | FileCheck %s + +enum E { + a = 1, + b = 2, + c = 3 +}; + +struct S { + E e1 : 10; +}; + +// CHECK-LABEL: define i32 @_Z4loadP1S +E load(S *s) { + // CHECK: [[LOAD:%.*]] = load i16, i16* {{.*}} + // CHECK: [[CLEAR:%.*]] = and i16 [[LOAD]], 1023 + // CHECK: [[CAST:%.*]] = zext i16 [[CLEAR]] to i32 + // CHECK: icmp ule i32 [[CAST]], 3, !nosanitize + // CHECK: call void @__ubsan_handle_load_invalid_value + return s->e1; +} Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -2938,7 +2938,7 @@ /// rvalue, returning the rvalue. RValue EmitLoadOfLValue(LValue V, SourceLocation Loc); RValue EmitLoadOfExtVectorElementLValue(LValue V); - RValue EmitLoadOfBitfieldLValue(LValue LV); + RValue EmitLoadOfBitfieldLValue(LValue LV, SourceLocation Loc); RValue EmitLoadOfGlobalRegLValue(LValue LV); /// EmitStoreThroughLValue - Store the specified rvalue into the specified Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -1537,10 +1537,11 @@ return EmitLoadOfGlobalRegLValue(LV); assert(LV.isBitField() && "Unknown LValue type!"); - return EmitLoadOfBitfieldLValue(LV); + return EmitLoadOfBitfieldLValue(LV, Loc); } -RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV) { +RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV, + SourceLocation Loc) { const CGBitFieldInfo &Info = LV.getBitFieldInfo(); // Get the output type. @@ -1565,7 +1566,7 @@ "bf.clear"); } Val = Builder.CreateIntCast(Val, ResLTy, Info.IsSigned, "bf.cast"); - + EmitScalarRangeCheck(Val, LV.getType(), Loc); return RValue::get(Val); }
[PATCH] D26316: [coroutines] Build and pass coroutine_handle to await_suspend.
GorNishanov added a comment. @EricWF, LGTM? https://reviews.llvm.org/D26316 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30423: [ubsan] Detect UB loads from bitfields
vsk added inline comments. Comment at: test/CodeGenCXX/ubsan-bitfields.cpp:21 + // CHECK: call void @__ubsan_handle_load_invalid_value + return s->e1; +} vsk wrote: > arphaman wrote: > > Can we avoid the check if the bitfield is 2 bits wide? > I don't think so, because if the user memset()'s the memory backing the > struct, we could still load a value outside of {1, 2, 3} from the bitfield. Sorry, I misread your question as 'if the enum can be represented in 2 bits'. You're right, the check can be skipped if the _bitfield_ is 2 bits wide. I think this can be handled along with the 1-bit unsigned BOOL case in a follow up. https://reviews.llvm.org/D30423 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30700: [Driver] Always add arch-specific-subdir to -rpath
pirama created this revision. This patch unconditionally adds -rpath of the arch-specific subdirectory in resource directory (instead of doing so only during native compilation). This patch also re-enables test arch-specific-libdir.c which was silently unsupported because of the REQUIRES tag 'linux'. https://reviews.llvm.org/D30700 Files: lib/Driver/Tools.cpp test/Driver/arch-specific-libdir-rpath.c test/Driver/arch-specific-libdir.c test/lit.cfg Index: test/lit.cfg === --- test/lit.cfg +++ test/lit.cfg @@ -397,10 +397,6 @@ if config.host_triple == config.target_triple: config.available_features.add("native") -# Test Driver/arch-specific-libdir-rpath.c is restricted to x86_64-linux -if re.match(r'^x86_64.*-linux', config.target_triple): -config.available_features.add("x86_64-linux") - # Case-insensitive file system def is_filesystem_case_insensitive(): handle, path = tempfile.mkstemp(prefix='case-test', dir=config.test_exec_root) Index: test/Driver/arch-specific-libdir.c === --- test/Driver/arch-specific-libdir.c +++ test/Driver/arch-specific-libdir.c @@ -1,8 +1,6 @@ // Test that the driver adds an arch-specific subdirectory in // {RESOURCE_DIR}/lib/linux to the search path. // -// REQUIRES: linux -// // RUN: %clang %s -### 2>&1 -target i386-unknown-linux \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \ // RUN: | FileCheck --check-prefixes=FILEPATH,ARCHDIR-i386 %s Index: test/Driver/arch-specific-libdir-rpath.c === --- test/Driver/arch-specific-libdir-rpath.c +++ test/Driver/arch-specific-libdir-rpath.c @@ -1,50 +1,53 @@ // Test that the driver adds an arch-specific subdirectory in -// {RESOURCE_DIR}/lib/linux to the linker search path and to '-rpath' for native -// compilations. -// -// -rpath only gets added during native compilation. To keep the test simple, -// just test for x86_64-linux native compilation. -// REQUIRES: x86_64-linux +// {RESOURCE_DIR}/lib/linux to the linker search path and to '-rpath' // // Add LIBPATH but no RPATH for -fsanitizer=address w/o -shared-libasan -// RUN: %clang %s -### 2>&1 -fsanitize=undefined \ +// RUN: %clang %s -### 2>&1 -target x86_64-linux -fsanitize=undefined \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \ -// RUN: | FileCheck --check-prefixes=FILEPATH,LIBPATH,NO-RPATH %s +// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,NO-RPATH %s // // Add LIBPATH, RPATH for -fsanitize=address -shared-libasan // RUN: %clang %s -### 2>&1 -target x86_64-linux \ // RUN: -fsanitize=address -shared-libasan \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \ -// RUN: | FileCheck --check-prefixes=FILEPATH,LIBPATH,RPATH %s +// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,RPATH-X86_64 %s +// +// Add LIBPATH, RPATH for -fsanitize=address -shared-libasan on aarch64 +// RUN: %clang %s -### 2>&1 -target aarch64-linux \ +// RUN: -fsanitize=address -shared-libasan \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \ +// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-AArch64,RPATH-AArch64 %s // // Add LIBPATH, RPATH with -fsanitize=address for Android // RUN: %clang %s -### 2>&1 -target x86_64-linux-android -fsanitize=address \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \ -// RUN: | FileCheck --check-prefixes=FILEPATH,LIBPATH,RPATH %s +// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,RPATH-X86_64 %s // // Add LIBPATH, RPATH for OpenMP -// RUN: %clang %s -### 2>&1 -fopenmp \ +// RUN: %clang %s -### 2>&1 -target x86_64-linux -fopenmp \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \ -// RUN: | FileCheck --check-prefixes=FILEPATH,LIBPATH,RPATH %s +// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,RPATH-X86_64 %s // // Add LIBPATH but no RPATH for ubsan (or any other sanitizer) // RUN: %clang %s -### 2>&1 -fsanitize=undefined \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \ -// RUN: | FileCheck --check-prefixes=FILEPATH,LIBPATH,NO-RPATH %s +// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,NO-RPATH %s // // Add LIBPATH but no RPATH if no sanitizer or runtime is specified // RUN: %clang %s -### 2>&1 \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \ -// RUN: | FileCheck --check-prefixes=FILEPATH,LIBPATH,NO-RPATH %s +// RUN: | FileCheck --check-prefixes=RESDIR,LIBPATH-X86_64,NO-RPATH %s // // Do not add LIBPATH or RPATH if arch-specific subdir doesn't exist // RUN: %clang %s -### 2>&1 \ // RUN: -resource-dir=%S/Inputs/resource_dir \ -// RUN: | FileCheck --check-prefixes=FILEPATH,NO-LIBPATH,NO-RPATH %s +// RUN: | FileCheck --check-prefixes=RESDIR,NO-LIBPATH,NO-RPATH %s // // -// FILEPATH: "-
Re: r296927 - Add arch-specific directory to search path
https://reviews.llvm.org/D30700 changes the driver to always add -rpath, irrespective of whether cross compiling or not. On Mon, Mar 6, 2017 at 10:29 AM, Benjamin Kramer wrote: > On Mon, Mar 6, 2017 at 7:00 PM, Pirama Arumuga Nainar > wrote: > > Adding Reid, Michal > > > > > > On Mon, Mar 6, 2017 at 5:01 AM, Benjamin Kramer > wrote: > >> > >> On Sat, Mar 4, 2017 at 12:20 AM, Pirama Arumuga Nainar via cfe-commits > >> wrote: > >> > Author: pirama > >> > Date: Fri Mar 3 17:20:49 2017 > >> > New Revision: 296927 > >> > > >> > URL: http://llvm.org/viewvc/llvm-project?rev=296927&view=rev > >> > Log: > >> > Add arch-specific directory to search path > >> > > >> > Summary: > >> > > >> > This change adds an arch-specific subdirectory in > /lib/ > >> > to the linker search path. This path also gets added as '-rpath' for > >> > native compilation if a runtime is linked in as a shared object. This > >> > allows arch-specific libraries to be installed alongside clang. > >> > > >> > Reviewers: danalbert, cbergstrom, javed.absar > >> > > >> > Subscribers: srhines > >> > > >> > Differential Revision: https://reviews.llvm.org/D30015 > >> > > >> > Added: > >> > cfe/trunk/test/Driver/Inputs/resource_dir_with_arch_subdir/ > >> > cfe/trunk/test/Driver/Inputs/resource_dir_with_arch_subdir/lib/ > >> > > >> > cfe/trunk/test/Driver/Inputs/resource_dir_with_arch_subdir/lib/linux/ > >> > > >> > cfe/trunk/test/Driver/Inputs/resource_dir_with_arch_subdir/ > lib/linux/aarch64/ > >> > > >> > cfe/trunk/test/Driver/Inputs/resource_dir_with_arch_subdir/ > lib/linux/aarch64/.keep > >> > > >> > cfe/trunk/test/Driver/Inputs/resource_dir_with_arch_subdir/ > lib/linux/arm/ > >> > > >> > cfe/trunk/test/Driver/Inputs/resource_dir_with_arch_subdir/ > lib/linux/arm/.keep > >> > > >> > cfe/trunk/test/Driver/Inputs/resource_dir_with_arch_subdir/ > lib/linux/i386/ > >> > > >> > cfe/trunk/test/Driver/Inputs/resource_dir_with_arch_subdir/ > lib/linux/i386/.keep > >> > > >> > cfe/trunk/test/Driver/Inputs/resource_dir_with_arch_subdir/ > lib/linux/x86_64/ > >> > > >> > cfe/trunk/test/Driver/Inputs/resource_dir_with_arch_subdir/ > lib/linux/x86_64/.keep > >> > cfe/trunk/test/Driver/arch-specific-libdir-rpath.c > >> > cfe/trunk/test/Driver/arch-specific-libdir.c > >> > Modified: > >> > cfe/trunk/include/clang/Driver/ToolChain.h > >> > cfe/trunk/lib/Driver/ToolChain.cpp > >> > cfe/trunk/lib/Driver/Tools.cpp > >> > cfe/trunk/test/lit.cfg > >> > > >> > Modified: cfe/trunk/include/clang/Driver/ToolChain.h > >> > URL: > >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/Driver/ToolChain.h?rev=296927&r1=296926&r2=296927&view=diff > >> > > >> > > == > >> > --- cfe/trunk/include/clang/Driver/ToolChain.h (original) > >> > +++ cfe/trunk/include/clang/Driver/ToolChain.h Fri Mar 3 17:20:49 > 2017 > >> > @@ -299,6 +299,11 @@ public: > >> >const char *getCompilerRTArgString(const llvm::opt::ArgList &Args, > >> > StringRef Component, > >> > bool Shared = false) const; > >> > + > >> > + // Returns /lib//. This is used by > >> > runtimes (such > >> > + // as OpenMP) to find arch-specific libraries. > >> > + std::string getArchSpecificLibPath() const; > >> > + > >> >/// needsProfileRT - returns true if instrumentation profile is on. > >> >static bool needsProfileRT(const llvm::opt::ArgList &Args); > >> > > >> > > >> > Modified: cfe/trunk/lib/Driver/ToolChain.cpp > >> > URL: > >> > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ > ToolChain.cpp?rev=296927&r1=296926&r2=296927&view=diff > >> > > >> > > == > >> > --- cfe/trunk/lib/Driver/ToolChain.cpp (original) > >> > +++ cfe/trunk/lib/Driver/ToolChain.cpp Fri Mar 3 17:20:49 2017 > >> > @@ -10,6 +10,7 @@ > >> > #include "clang/Driver/ToolChain.h" > >> > #include "Tools.h" > >> > #include "clang/Basic/ObjCRuntime.h" > >> > +#include "clang/Basic/VirtualFileSystem.h" > >> > #include "clang/Config/config.h" > >> > #include "clang/Driver/Action.h" > >> > #include "clang/Driver/Driver.h" > >> > @@ -74,6 +75,10 @@ ToolChain::ToolChain(const Driver &D, co > >> > if (!isThreadModelSupported(A->getValue())) > >> >D.Diag(diag::err_drv_invalid_thread_model_for_target) > >> ><< A->getValue() << A->getAsString(Args); > >> > + > >> > + std::string CandidateLibPath = getArchSpecificLibPath(); > >> > + if (getVFS().exists(CandidateLibPath)) > >> > +getFilePaths().push_back(CandidateLibPath); > >> > } > >> > > >> > ToolChain::~ToolChain() { > >> > @@ -320,6 +325,14 @@ const char *ToolChain::getCompilerRTArgS > >> >return Args.MakeArgString(getCompilerRT(Args, Component, Shared)); > >> > } > >> > > >> > +std::string ToolChain::getArchSpecificLibPath() const { > >> > + SmallString<128> Path
[PATCH] D23418: [analyzer] Added a reusable constraint system to the CloneDetector
v.g.vassilev added a comment. We were planning adding some extra unittests, too... 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] D30700: [Driver] Always add arch-specific-subdir to -rpath
rnk added a comment. Can you add a flag pair to control the insertion of rpath into the final binary? As things are currently, clang is basically leaking paths from the machine doing the linking into the final binary, which often will not run on the same machine. I was thinking `-f[no-]compiler-rt-rpath` or something, but openmp is not part of compiler-rt. Name recommendations welcome. We might also want to reconsider the default setting. https://reviews.llvm.org/D30700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libunwind] r297174 - Improve readability and correctness of the OS specific libunwind bits.
Author: ed Date: Tue Mar 7 12:15:52 2017 New Revision: 297174 URL: http://llvm.org/viewvc/llvm-project?rev=297174&view=rev Log: Improve readability and correctness of the OS specific libunwind bits. All of the access to __exidx_*, dl_iterate_phdr(), etc. is specific to the findUnwindSections() function. Right now all of the includes and declarations related to them are scattered throughout the source file. For example, for , we have a full list of operating systems guarding the #include, even though the code that uses dl_iterate_phdr() miraculously doesn't use the same list. Change the code so that findUnwindSections() is preceded by a block of #ifdefs that share the same structure as the function itself. First comes all of the macOS specific bits, followed by bare-metal ARM, followed by ELF EHABI + DWARF. This actually allows us to build a copy of libunwind without any specific ifdefs for NetBSD, CloudABI, etc. It likely also unbreaks the build of libunwind on FreeBSD/armv6, though I can't confirm. Reviewed by:compnerd Differential Revision: https://reviews.llvm.org/D30696 Modified: libunwind/trunk/src/AddressSpace.hpp Modified: libunwind/trunk/src/AddressSpace.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/AddressSpace.hpp?rev=297174&r1=297173&r2=297174&view=diff == --- libunwind/trunk/src/AddressSpace.hpp (original) +++ libunwind/trunk/src/AddressSpace.hpp Tue Mar 7 12:15:52 2017 @@ -34,32 +34,6 @@ namespace libunwind { #include "dwarf2.h" #include "Registers.hpp" -#if _LIBUNWIND_ARM_EHABI -#if defined(_LIBUNWIND_IS_BAREMETAL) -// When statically linked on bare-metal, the symbols for the EH table are looked -// up without going through the dynamic loader. -extern char __exidx_start; -extern char __exidx_end; -#else -#include -#endif // !defined(_LIBUNWIND_IS_BAREMETAL) -#endif // _LIBUNWIND_ARM_EHABI - -#if defined(__CloudABI__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \ -defined(__linux__) || defined(__NetBSD__) -#if _LIBUNWIND_SUPPORT_DWARF_UNWIND && _LIBUNWIND_SUPPORT_DWARF_INDEX -#include -// Macro for machine-independent access to the ELF program headers. This -// macro is not available on some systems (e.g., FreeBSD). On these -// systems the data structures are just called Elf_XXX. Define ElfW() -// locally. -#if !defined(ElfW) -#define ElfW(type) Elf_##type -#endif -#include "EHHeaderParser.hpp" -#endif -#endif - namespace libunwind { /// Used by findUnwindSections() to return info about needed sections. @@ -291,6 +265,7 @@ LocalAddressSpace::getEncodedP(pint_t &a } #ifdef __APPLE__ + struct dyld_unwind_sections { const struct mach_header* mh; @@ -336,6 +311,30 @@ LocalAddressSpace::getEncodedP(pint_t &a return true; } #endif + +#elif _LIBUNWIND_ARM_EHABI && defined(_LIBUNWIND_IS_BAREMETAL) + +// When statically linked on bare-metal, the symbols for the EH table are looked +// up without going through the dynamic loader. +extern char __exidx_start; +extern char __exidx_end; + +#elif _LIBUNWIND_ARM_EHABI || _LIBUNWIND_SUPPORT_DWARF_UNWIND + +// ELF-based systems may use dl_iterate_phdr() to access sections +// containing unwinding information. The ElfW() macro for pointer-size +// independent ELF header traversal is not provided by on some +// systems (e.g., FreeBSD). On these systems the data structures are +// just called Elf_XXX. Define ElfW() locally. +#include +#if !defined(ElfW) +#define ElfW(type) Elf_##type +#endif + +#if _LIBUNWIND_SUPPORT_DWARF_UNWIND +#include "EHHeaderParser.hpp" +#endif + #endif inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30705: clang-format: [JS] allow breaking after non-null assertions.
mprobst created this revision. Herald added a subscriber: klimek. Previously clang-format would not break after any !. However in TypeScript, ! can be used as a post fix operator for non-nullability: x.foo()!.bar()!; With this change, clang-format will wrap after the ! if it is likely a post-fix non null operator. https://reviews.llvm.org/D30705 Files: lib/Format/TokenAnnotator.cpp unittests/Format/FormatTestJS.cpp Index: unittests/Format/FormatTestJS.cpp === --- unittests/Format/FormatTestJS.cpp +++ unittests/Format/FormatTestJS.cpp @@ -1679,6 +1679,12 @@ verifyFormat("let x = (foo)!;\n"); verifyFormat("let x = foo! - 1;\n"); verifyFormat("let x = {foo: 1}!;\n"); + verifyFormat( + "let x = hello.foo()!\n" + ".foo()!\n" + ".foo()!\n" + ".foo()!;\n", + getGoogleJSStyleWithColumns(20)); } TEST_F(FormatTestJS, Conditional) { Index: lib/Format/TokenAnnotator.cpp === --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -2204,6 +2204,18 @@ return true; } +// Returns true if Tok is a postfix non-null assertion operator, as in +// `foo!.bar()`. +bool isJSNonNullOperator(const FormatToken &Tok) { + if (!Tok.Previous) +return false; + const FormatToken &Previous = *Tok.Previous; + return Tok.is(tok::exclaim) && + (Previous.isOneOf(tok::identifier, tok::r_paren, tok::r_square, + tok::r_brace) || + Previous.Tok.isLiteral()); +} + bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, const FormatToken &Right) { const FormatToken &Left = *Right.Previous; @@ -2277,10 +2289,7 @@ // locations that should have whitespace following are identified by the // above set of follower tokens. return false; -// Postfix non-null assertion operator, as in `foo!.bar()`. -if (Right.is(tok::exclaim) && (Left.isOneOf(tok::identifier, tok::r_paren, -tok::r_square, tok::r_brace) || - Left.Tok.isLiteral())) +if (isJSNonNullOperator(Right)) return false; if (Left.is(tok::exclaim) && Right.is(Keywords.kw_as)) return true; // "x! as string" @@ -2535,6 +2544,8 @@ return false; // must not break before as in 'x as type' casts if (Left.is(Keywords.kw_as)) return true; +if (isJSNonNullOperator(Left)) + return true; if (Left.is(Keywords.kw_declare) && Right.isOneOf(Keywords.kw_module, tok::kw_namespace, Keywords.kw_function, tok::kw_class, tok::kw_enum, Index: unittests/Format/FormatTestJS.cpp === --- unittests/Format/FormatTestJS.cpp +++ unittests/Format/FormatTestJS.cpp @@ -1679,6 +1679,12 @@ verifyFormat("let x = (foo)!;\n"); verifyFormat("let x = foo! - 1;\n"); verifyFormat("let x = {foo: 1}!;\n"); + verifyFormat( + "let x = hello.foo()!\n" + ".foo()!\n" + ".foo()!\n" + ".foo()!;\n", + getGoogleJSStyleWithColumns(20)); } TEST_F(FormatTestJS, Conditional) { Index: lib/Format/TokenAnnotator.cpp === --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -2204,6 +2204,18 @@ return true; } +// Returns true if Tok is a postfix non-null assertion operator, as in +// `foo!.bar()`. +bool isJSNonNullOperator(const FormatToken &Tok) { + if (!Tok.Previous) +return false; + const FormatToken &Previous = *Tok.Previous; + return Tok.is(tok::exclaim) && + (Previous.isOneOf(tok::identifier, tok::r_paren, tok::r_square, + tok::r_brace) || + Previous.Tok.isLiteral()); +} + bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, const FormatToken &Right) { const FormatToken &Left = *Right.Previous; @@ -2277,10 +2289,7 @@ // locations that should have whitespace following are identified by the // above set of follower tokens. return false; -// Postfix non-null assertion operator, as in `foo!.bar()`. -if (Right.is(tok::exclaim) && (Left.isOneOf(tok::identifier, tok::r_paren, -tok::r_square, tok::r_brace) || - Left.Tok.isLiteral())) +if (isJSNonNullOperator(Right)) return false; if (Left.is(tok::exclaim) && Right.is(Keywords.kw_as)) return true; // "x! as string" @@ -2535,6 +2544,8 @@ return false; // must not break before as in 'x as type' casts if (Left.is(Keywords.kw_as)) return true; +if (isJSNonNullOperator(Left)) + return true;
[libunwind] r297175 - Tidy up the way we include EHHeaderParser.hpp.
Author: ed Date: Tue Mar 7 12:21:51 2017 New Revision: 297175 URL: http://llvm.org/viewvc/llvm-project?rev=297175&view=rev Log: Tidy up the way we include EHHeaderParser.hpp. Other source files in the source tree tend to include this header file unconditionally. It also parses perfectly fine on ARM EHABI systems. Modified: libunwind/trunk/src/AddressSpace.hpp Modified: libunwind/trunk/src/AddressSpace.hpp URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/AddressSpace.hpp?rev=297175&r1=297174&r2=297175&view=diff == --- libunwind/trunk/src/AddressSpace.hpp (original) +++ libunwind/trunk/src/AddressSpace.hpp Tue Mar 7 12:21:51 2017 @@ -32,6 +32,7 @@ namespace libunwind { #include "libunwind.h" #include "config.h" #include "dwarf2.h" +#include "EHHeaderParser.hpp" #include "Registers.hpp" namespace libunwind { @@ -331,10 +332,6 @@ extern char __exidx_end; #define ElfW(type) Elf_##type #endif -#if _LIBUNWIND_SUPPORT_DWARF_UNWIND -#include "EHHeaderParser.hpp" -#endif - #endif inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30705: clang-format: [JS] allow breaking after non-null assertions.
djasper added inline comments. Comment at: lib/Format/TokenAnnotator.cpp:2292 return false; -// Postfix non-null assertion operator, as in `foo!.bar()`. -if (Right.is(tok::exclaim) && (Left.isOneOf(tok::identifier, tok::r_paren, -tok::r_square, tok::r_brace) || - Left.Tok.isLiteral())) +if (isJSNonNullOperator(Right)) return false; Hm. Generally, we try to set the TokenType instead of computing this information multiple times. It's not overly important here, but I can easily foresee that we are going to need to know what kind of "!" this is in ContinuationIndenter.cpp at some point. So I'd suggest to move this code into the huge mess that is determineTokenType (and define corresponding token type in FormatToken.h). https://reviews.llvm.org/D30705 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30705: clang-format: [JS] allow breaking after non-null assertions.
mprobst updated this revision to Diff 90889. mprobst added a comment. - Introduce TT_JsNonNullAssertion to centralize determining token types. https://reviews.llvm.org/D30705 Files: lib/Format/FormatToken.h lib/Format/TokenAnnotator.cpp unittests/Format/FormatTestJS.cpp Index: unittests/Format/FormatTestJS.cpp === --- unittests/Format/FormatTestJS.cpp +++ unittests/Format/FormatTestJS.cpp @@ -1679,6 +1679,12 @@ verifyFormat("let x = (foo)!;\n"); verifyFormat("let x = foo! - 1;\n"); verifyFormat("let x = {foo: 1}!;\n"); + verifyFormat( + "let x = hello.foo()!\n" + ".foo()!\n" + ".foo()!\n" + ".foo()!;\n", + getGoogleJSStyleWithColumns(20)); } TEST_F(FormatTestJS, Conditional) { Index: lib/Format/TokenAnnotator.cpp === --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -1052,7 +1052,22 @@ Contexts.back().CaretFound = true; } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) { Current.Type = determineIncrementUsage(Current); -} else if (Current.isOneOf(tok::exclaim, tok::tilde)) { +} else if (Current.is(tok::exclaim)) { + if (Style.Language == FormatStyle::LK_JavaScript) { +if (Current.Previous && +(Current.Previous->isOneOf(tok::identifier, tok::r_paren, + tok::r_square, tok::r_brace) || + Current.Previous->Tok.isLiteral())) { + Current.Type = TT_JsNonNullAssertion; + return; +} else if (Current.Next && + Current.Next->isOneOf(TT_BinaryOperator, Keywords.kw_as)) { + Current.Type = TT_JsNonNullAssertion; + return; +} + } + Current.Type = TT_UnaryOperator; +} else if (Current.is(tok::tilde)) { Current.Type = TT_UnaryOperator; } else if (Current.is(tok::question)) { if (Style.Language == FormatStyle::LK_JavaScript && @@ -2277,12 +2292,9 @@ // locations that should have whitespace following are identified by the // above set of follower tokens. return false; -// Postfix non-null assertion operator, as in `foo!.bar()`. -if (Right.is(tok::exclaim) && (Left.isOneOf(tok::identifier, tok::r_paren, -tok::r_square, tok::r_brace) || - Left.Tok.isLiteral())) +if (Right.is(TT_JsNonNullAssertion)) return false; -if (Left.is(tok::exclaim) && Right.is(Keywords.kw_as)) +if (Left.is(TT_JsNonNullAssertion) && Right.is(Keywords.kw_as)) return true; // "x! as string" } else if (Style.Language == FormatStyle::LK_Java) { if (Left.is(tok::r_square) && Right.is(tok::l_brace)) @@ -2535,6 +2547,8 @@ return false; // must not break before as in 'x as type' casts if (Left.is(Keywords.kw_as)) return true; +if (Left.is(TT_JsNonNullAssertion)) + return true; if (Left.is(Keywords.kw_declare) && Right.isOneOf(Keywords.kw_module, tok::kw_namespace, Keywords.kw_function, tok::kw_class, tok::kw_enum, Index: lib/Format/FormatToken.h === --- lib/Format/FormatToken.h +++ lib/Format/FormatToken.h @@ -53,6 +53,7 @@ TYPE(JavaAnnotation) \ TYPE(JsComputedPropertyName) \ TYPE(JsFatArrow) \ + TYPE(JsNonNullAssertion) \ TYPE(JsTypeColon) \ TYPE(JsTypeOperator) \ TYPE(JsTypeOptionalQuestion) \ Index: unittests/Format/FormatTestJS.cpp === --- unittests/Format/FormatTestJS.cpp +++ unittests/Format/FormatTestJS.cpp @@ -1679,6 +1679,12 @@ verifyFormat("let x = (foo)!;\n"); verifyFormat("let x = foo! - 1;\n"); verifyFormat("let x = {foo: 1}!;\n"); + verifyFormat( + "let x = hello.foo()!\n" + ".foo()!\n" + ".foo()!\n" + ".foo()!;\n", + getGoogleJSStyleWithColumns(20)); } TEST_F(FormatTestJS, Conditional) { Index: lib/Format/TokenAnnotator.cpp === --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -1052,7 +1052,22 @@ Contexts.back().CaretFound = true; } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) { Current.Type = determineIncrementUsage(Current); -} else if (Current.isOneOf(tok::exclaim, tok::tilde)) { +} else if (Current.is(tok::exclaim)) { + if (Style.Language == FormatStyle::LK_JavaScript) { +if (Current.Previous && +(Current.Previous->isOneOf(tok::identifier, tok::r_paren, + tok::r_square, tok::r_brace) || + Current.Previous->Tok.isLiteral())) { + Current.Type = TT_JsNonNullAssertion; +
[PATCH] D29923: Send UndefMacroDirective to MacroDefined callback
marsupial added a comment. ping https://reviews.llvm.org/D29923 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30711: [coroutines] update coro_end builtin to match llvm
GorNishanov created this revision. Herald added subscribers: EricWF, mehdi_amini. llvm.coro.end intrinsic now returns bool. Updating clang to match it. https://reviews.llvm.org/D30711 Files: include/clang/Basic/Builtins.def test/CodeGenCoroutines/coro-builtins.c Index: test/CodeGenCoroutines/coro-builtins.c === --- test/CodeGenCoroutines/coro-builtins.c +++ test/CodeGenCoroutines/coro-builtins.c @@ -43,7 +43,7 @@ __builtin_coro_free(__builtin_coro_frame()); // CHECK-NEXT: %[[FRAME6:.+]] = call i8* @llvm.coro.frame() - // CHECK-NEXT: call void @llvm.coro.end(i8* %[[FRAME6]], i1 false) + // CHECK-NEXT: call i1 @llvm.coro.end(i8* %[[FRAME6]], i1 false) __builtin_coro_end(__builtin_coro_frame(), 0); // CHECK-NEXT: call i8 @llvm.coro.suspend(token none, i1 true) Index: include/clang/Basic/Builtins.def === --- include/clang/Basic/Builtins.def +++ include/clang/Basic/Builtins.def @@ -1365,7 +1365,7 @@ BUILTIN(__builtin_coro_id, "v*Iiv*v*v*", "n") BUILTIN(__builtin_coro_alloc, "b", "n") BUILTIN(__builtin_coro_begin, "v*v*", "n") -BUILTIN(__builtin_coro_end, "vv*Ib", "n") +BUILTIN(__builtin_coro_end, "bv*Ib", "n") BUILTIN(__builtin_coro_suspend, "cIb", "n") BUILTIN(__builtin_coro_param, "bv*v*", "n") // OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions. Index: test/CodeGenCoroutines/coro-builtins.c === --- test/CodeGenCoroutines/coro-builtins.c +++ test/CodeGenCoroutines/coro-builtins.c @@ -43,7 +43,7 @@ __builtin_coro_free(__builtin_coro_frame()); // CHECK-NEXT: %[[FRAME6:.+]] = call i8* @llvm.coro.frame() - // CHECK-NEXT: call void @llvm.coro.end(i8* %[[FRAME6]], i1 false) + // CHECK-NEXT: call i1 @llvm.coro.end(i8* %[[FRAME6]], i1 false) __builtin_coro_end(__builtin_coro_frame(), 0); // CHECK-NEXT: call i8 @llvm.coro.suspend(token none, i1 true) Index: include/clang/Basic/Builtins.def === --- include/clang/Basic/Builtins.def +++ include/clang/Basic/Builtins.def @@ -1365,7 +1365,7 @@ BUILTIN(__builtin_coro_id, "v*Iiv*v*v*", "n") BUILTIN(__builtin_coro_alloc, "b", "n") BUILTIN(__builtin_coro_begin, "v*v*", "n") -BUILTIN(__builtin_coro_end, "vv*Ib", "n") +BUILTIN(__builtin_coro_end, "bv*Ib", "n") BUILTIN(__builtin_coro_suspend, "cIb", "n") BUILTIN(__builtin_coro_param, "bv*v*", "n") // OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30663: Use filename in linemarker when compiling preprocessed source (Revised)
inglorion accepted this revision. inglorion added a comment. This revision is now accepted and ready to land. Fixing the other issues in a follow-up seems fine. This lgtm. https://reviews.llvm.org/D30663 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297187 - [analyzer] Fix crashes in CastToStruct checker for undefined structs
Author: danielmarjamaki Date: Tue Mar 7 13:20:48 2017 New Revision: 297187 URL: http://llvm.org/viewvc/llvm-project?rev=297187&view=rev Log: [analyzer] Fix crashes in CastToStruct checker for undefined structs This crash was reported in https://bugs.llvm.org//show_bug.cgi?id=31173 Differential Revision: https://reviews.llvm.org/D28297 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp cfe/trunk/test/Analysis/cast-to-struct.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp?rev=297187&r1=297186&r2=297187&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp Tue Mar 7 13:20:48 2017 @@ -84,6 +84,10 @@ bool CastToStructVisitor::VisitCastExpr( if (!VD || VD->getType()->isReferenceType()) return true; +if (ToPointeeTy->isIncompleteType() || +OrigPointeeTy->isIncompleteType()) + return true; + // Warn when there is widening cast. unsigned ToWidth = Ctx.getTypeInfo(ToPointeeTy).Width; unsigned OrigWidth = Ctx.getTypeInfo(OrigPointeeTy).Width; Modified: cfe/trunk/test/Analysis/cast-to-struct.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cast-to-struct.cpp?rev=297187&r1=297186&r2=297187&view=diff == --- cfe/trunk/test/Analysis/cast-to-struct.cpp (original) +++ cfe/trunk/test/Analysis/cast-to-struct.cpp Tue Mar 7 13:20:48 2017 @@ -65,3 +65,17 @@ void intToStruct(int *P) { void *VP = P; Abc = (struct ABC *)VP; } + +// https://llvm.org/bugs/show_bug.cgi?id=31173 +void dontCrash1(struct AB X) { + struct UndefS *S = (struct UndefS *)&X; +} + +struct S; +struct T { + struct S *P; +}; +extern struct S Var1, Var2; +void dontCrash2() { + ((struct T *) &Var1)->P = &Var2; +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28297: [StaticAnalyzer] Fix crash in CastToStructChecker
This revision was automatically updated to reflect the committed changes. Closed by commit rL297187: [analyzer] Fix crashes in CastToStruct checker for undefined structs (authored by danielmarjamaki). Changed prior to commit: https://reviews.llvm.org/D28297?vs=89507&id=90900#toc Repository: rL LLVM https://reviews.llvm.org/D28297 Files: cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp cfe/trunk/test/Analysis/cast-to-struct.cpp Index: cfe/trunk/test/Analysis/cast-to-struct.cpp === --- cfe/trunk/test/Analysis/cast-to-struct.cpp +++ cfe/trunk/test/Analysis/cast-to-struct.cpp @@ -65,3 +65,17 @@ void *VP = P; Abc = (struct ABC *)VP; } + +// https://llvm.org/bugs/show_bug.cgi?id=31173 +void dontCrash1(struct AB X) { + struct UndefS *S = (struct UndefS *)&X; +} + +struct S; +struct T { + struct S *P; +}; +extern struct S Var1, Var2; +void dontCrash2() { + ((struct T *) &Var1)->P = &Var2; +} Index: cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp === --- cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp @@ -84,6 +84,10 @@ if (!VD || VD->getType()->isReferenceType()) return true; +if (ToPointeeTy->isIncompleteType() || +OrigPointeeTy->isIncompleteType()) + return true; + // Warn when there is widening cast. unsigned ToWidth = Ctx.getTypeInfo(ToPointeeTy).Width; unsigned OrigWidth = Ctx.getTypeInfo(OrigPointeeTy).Width; Index: cfe/trunk/test/Analysis/cast-to-struct.cpp === --- cfe/trunk/test/Analysis/cast-to-struct.cpp +++ cfe/trunk/test/Analysis/cast-to-struct.cpp @@ -65,3 +65,17 @@ void *VP = P; Abc = (struct ABC *)VP; } + +// https://llvm.org/bugs/show_bug.cgi?id=31173 +void dontCrash1(struct AB X) { + struct UndefS *S = (struct UndefS *)&X; +} + +struct S; +struct T { + struct S *P; +}; +extern struct S Var1, Var2; +void dontCrash2() { + ((struct T *) &Var1)->P = &Var2; +} Index: cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp === --- cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp @@ -84,6 +84,10 @@ if (!VD || VD->getType()->isReferenceType()) return true; +if (ToPointeeTy->isIncompleteType() || +OrigPointeeTy->isIncompleteType()) + return true; + // Warn when there is widening cast. unsigned ToWidth = Ctx.getTypeInfo(ToPointeeTy).Width; unsigned OrigWidth = Ctx.getTypeInfo(OrigPointeeTy).Width; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [libunwind] r297174 - Improve readability and correctness of the OS specific libunwind bits.
Hi Ed, Could you please always include cfe-commits as a subscriber in you phab reviews? We would like to be aware of these changes in advance before they land. Thanks. / Asiri On 7 Mar 2017 6:27 p.m., "Ed Schouten via cfe-commits" < cfe-commits@lists.llvm.org> wrote: > Author: ed > Date: Tue Mar 7 12:15:52 2017 > New Revision: 297174 > > URL: http://llvm.org/viewvc/llvm-project?rev=297174&view=rev > Log: > Improve readability and correctness of the OS specific libunwind bits. > > All of the access to __exidx_*, dl_iterate_phdr(), etc. is specific to > the findUnwindSections() function. Right now all of the includes and > declarations related to them are scattered throughout the source file. > For example, for , we have a full list of operating systems > guarding the #include, even though the code that uses dl_iterate_phdr() > miraculously doesn't use the same list. > > Change the code so that findUnwindSections() is preceded by a block of > #ifdefs that share the same structure as the function itself. First > comes all of the macOS specific bits, followed by bare-metal ARM, > followed by ELF EHABI + DWARF. > > This actually allows us to build a copy of libunwind without any > specific ifdefs for NetBSD, CloudABI, etc. It likely also unbreaks the > build of libunwind on FreeBSD/armv6, though I can't confirm. > > Reviewed by:compnerd > Differential Revision: https://reviews.llvm.org/D30696 > > Modified: > libunwind/trunk/src/AddressSpace.hpp > > Modified: libunwind/trunk/src/AddressSpace.hpp > URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/ > AddressSpace.hpp?rev=297174&r1=297173&r2=297174&view=diff > > == > --- libunwind/trunk/src/AddressSpace.hpp (original) > +++ libunwind/trunk/src/AddressSpace.hpp Tue Mar 7 12:15:52 2017 > @@ -34,32 +34,6 @@ namespace libunwind { > #include "dwarf2.h" > #include "Registers.hpp" > > -#if _LIBUNWIND_ARM_EHABI > -#if defined(_LIBUNWIND_IS_BAREMETAL) > -// When statically linked on bare-metal, the symbols for the EH table are > looked > -// up without going through the dynamic loader. > -extern char __exidx_start; > -extern char __exidx_end; > -#else > -#include > -#endif // !defined(_LIBUNWIND_IS_BAREMETAL) > -#endif // _LIBUNWIND_ARM_EHABI > - > -#if defined(__CloudABI__) || defined(__FreeBSD__) || defined(__Fuchsia__) > || \ > -defined(__linux__) || defined(__NetBSD__) > -#if _LIBUNWIND_SUPPORT_DWARF_UNWIND && _LIBUNWIND_SUPPORT_DWARF_INDEX > -#include > -// Macro for machine-independent access to the ELF program headers. This > -// macro is not available on some systems (e.g., FreeBSD). On these > -// systems the data structures are just called Elf_XXX. Define ElfW() > -// locally. > -#if !defined(ElfW) > -#define ElfW(type) Elf_##type > -#endif > -#include "EHHeaderParser.hpp" > -#endif > -#endif > - > namespace libunwind { > > /// Used by findUnwindSections() to return info about needed sections. > @@ -291,6 +265,7 @@ LocalAddressSpace::getEncodedP(pint_t &a > } > > #ifdef __APPLE__ > + >struct dyld_unwind_sections >{ > const struct mach_header* mh; > @@ -336,6 +311,30 @@ LocalAddressSpace::getEncodedP(pint_t &a >return true; > } >#endif > + > +#elif _LIBUNWIND_ARM_EHABI && defined(_LIBUNWIND_IS_BAREMETAL) > + > +// When statically linked on bare-metal, the symbols for the EH table are > looked > +// up without going through the dynamic loader. > +extern char __exidx_start; > +extern char __exidx_end; > + > +#elif _LIBUNWIND_ARM_EHABI || _LIBUNWIND_SUPPORT_DWARF_UNWIND > + > +// ELF-based systems may use dl_iterate_phdr() to access sections > +// containing unwinding information. The ElfW() macro for pointer-size > +// independent ELF header traversal is not provided by on some > +// systems (e.g., FreeBSD). On these systems the data structures are > +// just called Elf_XXX. Define ElfW() locally. > +#include > +#if !defined(ElfW) > +#define ElfW(type) Elf_##type > +#endif > + > +#if _LIBUNWIND_SUPPORT_DWARF_UNWIND > +#include "EHHeaderParser.hpp" > +#endif > + > #endif > > inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, > > > ___ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Disable fms-extensions?
Hello, Clang implements MS extensions when using -fms-extension. On windows this option is enabled by default. Is there any way of disabling it to mirror the behavior of the /Za (-permissive-) option of CL? Thanks, -Zahira ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30663: Use filename in linemarker when compiling preprocessed source (Revised)
This revision was automatically updated to reflect the committed changes. Closed by commit rL297194: Use filename in linemarker when compiling preprocessed source (Revised) (authored by twoh). Changed prior to commit: https://reviews.llvm.org/D30663?vs=90735&id=90912#toc Repository: rL LLVM https://reviews.llvm.org/D30663 Files: cfe/trunk/include/clang/Frontend/FrontendOptions.h cfe/trunk/lib/Frontend/FrontendAction.cpp cfe/trunk/test/Frontend/preprocessed-input.i Index: cfe/trunk/include/clang/Frontend/FrontendOptions.h === --- cfe/trunk/include/clang/Frontend/FrontendOptions.h +++ cfe/trunk/include/clang/Frontend/FrontendOptions.h @@ -81,7 +81,7 @@ IK_LLVM_IR }; - + /// \brief An input file for the front end. class FrontendInputFile { /// \brief The file name, or "-" to read from standard input. @@ -109,6 +109,13 @@ bool isEmpty() const { return File.empty() && Buffer == nullptr; } bool isFile() const { return !isBuffer(); } bool isBuffer() const { return Buffer != nullptr; } + bool isPreprocessed() const { +return Kind == IK_PreprocessedC || + Kind == IK_PreprocessedCXX || + Kind == IK_PreprocessedObjC || + Kind == IK_PreprocessedObjCXX || + Kind == IK_PreprocessedCuda; + } StringRef getFile() const { assert(isFile()); Index: cfe/trunk/test/Frontend/preprocessed-input.i === --- cfe/trunk/test/Frontend/preprocessed-input.i +++ cfe/trunk/test/Frontend/preprocessed-input.i @@ -0,0 +1,10 @@ +# 1 "preprocessed-input.c" +# 1 "" 1 +# 1 "" 3 +# 318 "" 3 +# 1 "" 1 +# 1 "" 2 +# 1 "preprocessed-input.c" 2 + +// RUN: %clang -emit-llvm -S -o - %s | FileCheck %s +// CHECK: source_filename = "preprocessed-input.c"{{$}} Index: cfe/trunk/lib/Frontend/FrontendAction.cpp === --- cfe/trunk/lib/Frontend/FrontendAction.cpp +++ cfe/trunk/lib/Frontend/FrontendAction.cpp @@ -19,6 +19,7 @@ #include "clang/Frontend/MultiplexConsumer.h" #include "clang/Frontend/Utils.h" #include "clang/Lex/HeaderSearch.h" +#include "clang/Lex/LiteralSupport.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" #include "clang/Parse/ParseAST.h" @@ -187,6 +188,42 @@ return llvm::make_unique(std::move(Consumers)); } +// For preprocessed files, if the first line is the linemarker and specifies +// the original source file name, use that name as the input file name. +static bool ReadOriginalFileName(CompilerInstance &CI, std::string &InputFile) +{ + bool Invalid = false; + auto &SourceMgr = CI.getSourceManager(); + auto MainFileID = SourceMgr.getMainFileID(); + const auto *MainFileBuf = SourceMgr.getBuffer(MainFileID, &Invalid); + if (Invalid) +return false; + + std::unique_ptr RawLexer( + new Lexer(MainFileID, MainFileBuf, SourceMgr, CI.getLangOpts())); + + // If the first line has the syntax of + // + // # NUM "FILENAME" + // + // we use FILENAME as the input file name. + Token T; + if (RawLexer->LexFromRawLexer(T) || T.getKind() != tok::hash) +return false; + if (RawLexer->LexFromRawLexer(T) || T.isAtStartOfLine() || + T.getKind() != tok::numeric_constant) +return false; + RawLexer->LexFromRawLexer(T); + if (T.isAtStartOfLine() || T.getKind() != tok::string_literal) +return false; + + StringLiteralParser Literal(T, CI.getPreprocessor()); + if (Literal.hadError) +return false; + InputFile = Literal.GetString().str(); + return true; +} + bool FrontendAction::BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input) { assert(!Instance && "Already processing a source file!"); @@ -338,6 +375,13 @@ if (!isModelParsingAction()) CI.createASTContext(); +// For preprocessed files, check if the first line specifies the original +// source file name with a linemarker. +std::string OrigFile; +if (Input.isPreprocessed()) + if (ReadOriginalFileName(CI, OrigFile)) +InputFile = OrigFile; + std::unique_ptr Consumer = CreateWrappedASTConsumer(CI, InputFile); if (!Consumer) @@ -430,9 +474,9 @@ // If there is a layout overrides file, attach an external AST source that // provides the layouts from that file. - if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && + if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && CI.hasASTContext() && !CI.getASTContext().getExternalSource()) { -IntrusiveRefCntPtr +IntrusiveRefCntPtr Override(new LayoutOverrideSource( CI.getFrontendOpts().OverrideRecordLayoutsFile)); CI.getASTContext().setExternalSource(Override); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297194 - Use filename in linemarker when compiling preprocessed source (Revised)
Author: twoh Date: Tue Mar 7 14:20:23 2017 New Revision: 297194 URL: http://llvm.org/viewvc/llvm-project?rev=297194&view=rev Log: Use filename in linemarker when compiling preprocessed source (Revised) Summary: This is a revised version of D28796. Included test is changed to resolve the target compatibility issue reported (rL293032). Reviewers: inglorion, dblaikie, echristo, aprantl, probinson Reviewed By: inglorion Subscribers: mehdi_amini, cfe-commits Differential Revision: https://reviews.llvm.org/D30663 Added: cfe/trunk/test/Frontend/preprocessed-input.i Modified: cfe/trunk/include/clang/Frontend/FrontendOptions.h cfe/trunk/lib/Frontend/FrontendAction.cpp Modified: cfe/trunk/include/clang/Frontend/FrontendOptions.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendOptions.h?rev=297194&r1=297193&r2=297194&view=diff == --- cfe/trunk/include/clang/Frontend/FrontendOptions.h (original) +++ cfe/trunk/include/clang/Frontend/FrontendOptions.h Tue Mar 7 14:20:23 2017 @@ -81,7 +81,7 @@ enum InputKind { IK_LLVM_IR }; - + /// \brief An input file for the front end. class FrontendInputFile { /// \brief The file name, or "-" to read from standard input. @@ -109,6 +109,13 @@ public: bool isEmpty() const { return File.empty() && Buffer == nullptr; } bool isFile() const { return !isBuffer(); } bool isBuffer() const { return Buffer != nullptr; } + bool isPreprocessed() const { +return Kind == IK_PreprocessedC || + Kind == IK_PreprocessedCXX || + Kind == IK_PreprocessedObjC || + Kind == IK_PreprocessedObjCXX || + Kind == IK_PreprocessedCuda; + } StringRef getFile() const { assert(isFile()); Modified: cfe/trunk/lib/Frontend/FrontendAction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendAction.cpp?rev=297194&r1=297193&r2=297194&view=diff == --- cfe/trunk/lib/Frontend/FrontendAction.cpp (original) +++ cfe/trunk/lib/Frontend/FrontendAction.cpp Tue Mar 7 14:20:23 2017 @@ -19,6 +19,7 @@ #include "clang/Frontend/MultiplexConsumer.h" #include "clang/Frontend/Utils.h" #include "clang/Lex/HeaderSearch.h" +#include "clang/Lex/LiteralSupport.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" #include "clang/Parse/ParseAST.h" @@ -187,6 +188,42 @@ FrontendAction::CreateWrappedASTConsumer return llvm::make_unique(std::move(Consumers)); } +// For preprocessed files, if the first line is the linemarker and specifies +// the original source file name, use that name as the input file name. +static bool ReadOriginalFileName(CompilerInstance &CI, std::string &InputFile) +{ + bool Invalid = false; + auto &SourceMgr = CI.getSourceManager(); + auto MainFileID = SourceMgr.getMainFileID(); + const auto *MainFileBuf = SourceMgr.getBuffer(MainFileID, &Invalid); + if (Invalid) +return false; + + std::unique_ptr RawLexer( + new Lexer(MainFileID, MainFileBuf, SourceMgr, CI.getLangOpts())); + + // If the first line has the syntax of + // + // # NUM "FILENAME" + // + // we use FILENAME as the input file name. + Token T; + if (RawLexer->LexFromRawLexer(T) || T.getKind() != tok::hash) +return false; + if (RawLexer->LexFromRawLexer(T) || T.isAtStartOfLine() || + T.getKind() != tok::numeric_constant) +return false; + RawLexer->LexFromRawLexer(T); + if (T.isAtStartOfLine() || T.getKind() != tok::string_literal) +return false; + + StringLiteralParser Literal(T, CI.getPreprocessor()); + if (Literal.hadError) +return false; + InputFile = Literal.GetString().str(); + return true; +} + bool FrontendAction::BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input) { assert(!Instance && "Already processing a source file!"); @@ -338,6 +375,13 @@ bool FrontendAction::BeginSourceFile(Com if (!isModelParsingAction()) CI.createASTContext(); +// For preprocessed files, check if the first line specifies the original +// source file name with a linemarker. +std::string OrigFile; +if (Input.isPreprocessed()) + if (ReadOriginalFileName(CI, OrigFile)) +InputFile = OrigFile; + std::unique_ptr Consumer = CreateWrappedASTConsumer(CI, InputFile); if (!Consumer) @@ -430,9 +474,9 @@ bool FrontendAction::BeginSourceFile(Com // If there is a layout overrides file, attach an external AST source that // provides the layouts from that file. - if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && + if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && CI.hasASTContext() && !CI.getASTContext().getExternalSource()) { -IntrusiveRefCntPtr +IntrusiveRefCntPtr Override(new LayoutOverrideSource( CI.getFron
[libunwind] r297221 - Creating release candidate rc4 from release_400 branch
Author: hans Date: Tue Mar 7 14:59:01 2017 New Revision: 297221 URL: http://llvm.org/viewvc/llvm-project?rev=297221&view=rev Log: Creating release candidate rc4 from release_400 branch Added: libunwind/tags/RELEASE_400/rc4/ (props changed) - copied from r297220, libunwind/branches/release_40/ Propchange: libunwind/tags/RELEASE_400/rc4/ -- svn:mergeinfo = /libunwind/trunk:292723,296358-296359 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxxabi] r297215 - Creating release candidate rc4 from release_400 branch
Author: hans Date: Tue Mar 7 14:58:42 2017 New Revision: 297215 URL: http://llvm.org/viewvc/llvm-project?rev=297215&view=rev Log: Creating release candidate rc4 from release_400 branch Added: libcxxabi/tags/RELEASE_400/rc4/ (props changed) - copied from r297214, libcxxabi/branches/release_40/ Propchange: libcxxabi/tags/RELEASE_400/rc4/ -- svn:mergeinfo = /libcxxabi/trunk:292135,292418,292638 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r297214 - Creating release candidate rc4 from release_400 branch
Author: hans Date: Tue Mar 7 14:58:39 2017 New Revision: 297214 URL: http://llvm.org/viewvc/llvm-project?rev=297214&view=rev Log: Creating release candidate rc4 from release_400 branch Added: libcxx/tags/RELEASE_400/rc4/ (props changed) - copied from r297213, libcxx/branches/release_40/ Propchange: libcxx/tags/RELEASE_400/rc4/ -- --- svn:mergeinfo (added) +++ svn:mergeinfo Tue Mar 7 14:58:39 2017 @@ -0,0 +1,2 @@ +/libcxx/branches/apple:136569-137939 +/libcxx/trunk:292013,292091,292607,292990,293154,293197,293581,294133,294142,294431 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297224 - [coroutines] update coro_end builtin to match llvm
Author: gornishanov Date: Tue Mar 7 15:01:08 2017 New Revision: 297224 URL: http://llvm.org/viewvc/llvm-project?rev=297224&view=rev Log: [coroutines] update coro_end builtin to match llvm Summary: llvm.coro.end intrinsic now returns bool. Updating clang to match it. Reviewers: GorNishanov, rsmith Reviewed By: rsmith Subscribers: mehdi_amini, cfe-commits, EricWF Differential Revision: https://reviews.llvm.org/D30711 Modified: cfe/trunk/include/clang/Basic/Builtins.def cfe/trunk/test/CodeGenCoroutines/coro-builtins.c Modified: cfe/trunk/include/clang/Basic/Builtins.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=297224&r1=297223&r2=297224&view=diff == --- cfe/trunk/include/clang/Basic/Builtins.def (original) +++ cfe/trunk/include/clang/Basic/Builtins.def Tue Mar 7 15:01:08 2017 @@ -1365,7 +1365,7 @@ BUILTIN(__builtin_coro_free, "v*v*", "n" BUILTIN(__builtin_coro_id, "v*Iiv*v*v*", "n") BUILTIN(__builtin_coro_alloc, "b", "n") BUILTIN(__builtin_coro_begin, "v*v*", "n") -BUILTIN(__builtin_coro_end, "vv*Ib", "n") +BUILTIN(__builtin_coro_end, "bv*Ib", "n") BUILTIN(__builtin_coro_suspend, "cIb", "n") BUILTIN(__builtin_coro_param, "bv*v*", "n") // OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions. Modified: cfe/trunk/test/CodeGenCoroutines/coro-builtins.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCoroutines/coro-builtins.c?rev=297224&r1=297223&r2=297224&view=diff == --- cfe/trunk/test/CodeGenCoroutines/coro-builtins.c (original) +++ cfe/trunk/test/CodeGenCoroutines/coro-builtins.c Tue Mar 7 15:01:08 2017 @@ -43,7 +43,7 @@ void f(int n) { __builtin_coro_free(__builtin_coro_frame()); // CHECK-NEXT: %[[FRAME6:.+]] = call i8* @llvm.coro.frame() - // CHECK-NEXT: call void @llvm.coro.end(i8* %[[FRAME6]], i1 false) + // CHECK-NEXT: call i1 @llvm.coro.end(i8* %[[FRAME6]], i1 false) __builtin_coro_end(__builtin_coro_frame(), 0); // CHECK-NEXT: call i8 @llvm.coro.suspend(token none, i1 true) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30415: Fix -mno-altivec cannot overwrite -maltivec option
kuang_he updated this revision to Diff 90927. kuang_he edited the summary of this revision. kuang_he added a comment. Add fix and update test case for -fzvector option. https://reviews.llvm.org/D30415 Files: lib/Driver/Tools.cpp test/Driver/ppc-features.cpp test/Driver/systemz-features.cpp Index: test/Driver/systemz-features.cpp === --- test/Driver/systemz-features.cpp +++ test/Driver/systemz-features.cpp @@ -24,3 +24,9 @@ // RUN: %clang -target s390x-unknown-linux-gnu %s -mvx -mno-vx -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOVX %s // CHECK-NOVX: "-target-feature" "-vector" // CHECK-NOVX-NOT: "-target-feature" "+vector" +// +// RUN: %clang -target s390x-unknown-linux-gnu %s -fzvector -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-ZVECTOR %s +// CHECK-ZVECTOR: "-fzvector" +// +// RUN: %clang -target s390x-unknown-linux-gnu %s -fzvector -fno-zvector -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NO-ZVECTOR %s +// CHECK-NO-ZVECTOR-NOT: "-fzvector" Index: test/Driver/ppc-features.cpp === --- test/Driver/ppc-features.cpp +++ test/Driver/ppc-features.cpp @@ -63,51 +63,67 @@ // RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-1 %s // CHECK-1: "-target-feature" "-altivec" +// CHECK-1-NOT: "-faltivec" // RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-altivec -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-2 %s // CHECK-2: "-target-feature" "-altivec" +// CHECK-2-NOT: "-faltivec" // RUN: %clang -target powerpc64-unknown-linux-gnu %s -faltivec -mno-altivec -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-3 %s // CHECK-3: "-target-feature" "-altivec" +// CHECK-3-NOT: "-faltivec" // RUN: %clang -target powerpc64-unknown-linux-gnu %s -maltivec -fno-altivec -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-4 %s // CHECK-4: "-target-feature" "-altivec" +// CHECK-4-NOT: "-faltivec" // RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-altivec -faltivec -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-5 %s -// CHECK-5-NOT: "-target-feature" "-altivec" +// CHECK-5: "-target-feature" "+altivec" +// CHECK-5: "-faltivec" // RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -maltivec -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-6 %s -// CHECK-6-NOT: "-target-feature" "-altivec" +// CHECK-6: "-target-feature" "+altivec" +// CHECK-6: "-faltivec" // RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=7400 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-7 %s // CHECK-7: "-target-feature" "-altivec" +// CHECK-7-NOT: "-faltivec" // RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=g4 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-8 %s // CHECK-8: "-target-feature" "-altivec" +// CHECK-8-NOT: "-faltivec" // RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=7450 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-9 %s // CHECK-9: "-target-feature" "-altivec" +// CHECK-9-NOT: "-faltivec" // RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=g4+ -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-10 %s // CHECK-10: "-target-feature" "-altivec" +// CHECK-10-NOT: "-faltivec" // RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=970 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-11 %s // CHECK-11: "-target-feature" "-altivec" +// CHECK-11-NOT: "-faltivec" // RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=g5 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-12 %s // CHECK-12: "-target-feature" "-altivec" +// CHECK-12-NOT: "-faltivec" // RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=pwr6 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-13 %s // CHECK-13: "-target-feature" "-altivec" +// CHECK-13-NOT: "-faltivec" // RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=pwr7 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-14 %s // CHECK-14: "-target-feature" "-altivec" +// CHECK-14-NOT: "-faltivec" // RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=pwr8 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-15 %s // CHECK-15: "-target-feature" "-altivec" +// CHECK-15-NOT: "-faltivec" // RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=ppc64 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-16 %s // CHECK-16: "-target-feature" "-altivec" +// CHECK-16-NOT: "-faltivec" // RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-qpx -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOQPX %s // CHECK-NOQPX: "-target-feature" "-qpx" Index: lib/Driver/Tools.cpp === --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -4207,8 +4207,13 @@ CmdArgs.push_
[PATCH] D30711: [coroutines] update coro_end builtin to match llvm
This revision was automatically updated to reflect the committed changes. Closed by commit rL297224: [coroutines] update coro_end builtin to match llvm (authored by GorNishanov). Changed prior to commit: https://reviews.llvm.org/D30711?vs=90897&id=90928#toc Repository: rL LLVM https://reviews.llvm.org/D30711 Files: cfe/trunk/include/clang/Basic/Builtins.def cfe/trunk/test/CodeGenCoroutines/coro-builtins.c Index: cfe/trunk/include/clang/Basic/Builtins.def === --- cfe/trunk/include/clang/Basic/Builtins.def +++ cfe/trunk/include/clang/Basic/Builtins.def @@ -1365,7 +1365,7 @@ BUILTIN(__builtin_coro_id, "v*Iiv*v*v*", "n") BUILTIN(__builtin_coro_alloc, "b", "n") BUILTIN(__builtin_coro_begin, "v*v*", "n") -BUILTIN(__builtin_coro_end, "vv*Ib", "n") +BUILTIN(__builtin_coro_end, "bv*Ib", "n") BUILTIN(__builtin_coro_suspend, "cIb", "n") BUILTIN(__builtin_coro_param, "bv*v*", "n") // OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions. Index: cfe/trunk/test/CodeGenCoroutines/coro-builtins.c === --- cfe/trunk/test/CodeGenCoroutines/coro-builtins.c +++ cfe/trunk/test/CodeGenCoroutines/coro-builtins.c @@ -43,7 +43,7 @@ __builtin_coro_free(__builtin_coro_frame()); // CHECK-NEXT: %[[FRAME6:.+]] = call i8* @llvm.coro.frame() - // CHECK-NEXT: call void @llvm.coro.end(i8* %[[FRAME6]], i1 false) + // CHECK-NEXT: call i1 @llvm.coro.end(i8* %[[FRAME6]], i1 false) __builtin_coro_end(__builtin_coro_frame(), 0); // CHECK-NEXT: call i8 @llvm.coro.suspend(token none, i1 true) Index: cfe/trunk/include/clang/Basic/Builtins.def === --- cfe/trunk/include/clang/Basic/Builtins.def +++ cfe/trunk/include/clang/Basic/Builtins.def @@ -1365,7 +1365,7 @@ BUILTIN(__builtin_coro_id, "v*Iiv*v*v*", "n") BUILTIN(__builtin_coro_alloc, "b", "n") BUILTIN(__builtin_coro_begin, "v*v*", "n") -BUILTIN(__builtin_coro_end, "vv*Ib", "n") +BUILTIN(__builtin_coro_end, "bv*Ib", "n") BUILTIN(__builtin_coro_suspend, "cIb", "n") BUILTIN(__builtin_coro_param, "bv*v*", "n") // OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions. Index: cfe/trunk/test/CodeGenCoroutines/coro-builtins.c === --- cfe/trunk/test/CodeGenCoroutines/coro-builtins.c +++ cfe/trunk/test/CodeGenCoroutines/coro-builtins.c @@ -43,7 +43,7 @@ __builtin_coro_free(__builtin_coro_frame()); // CHECK-NEXT: %[[FRAME6:.+]] = call i8* @llvm.coro.frame() - // CHECK-NEXT: call void @llvm.coro.end(i8* %[[FRAME6]], i1 false) + // CHECK-NEXT: call i1 @llvm.coro.end(i8* %[[FRAME6]], i1 false) __builtin_coro_end(__builtin_coro_frame(), 0); // CHECK-NEXT: call i8 @llvm.coro.suspend(token none, i1 true) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28445: [Analyzer] Extend taint propagation and checking
zaks.anna added a comment. @vlad.tsyrklevich, Do you have commit access or should we commit on your behalf? https://reviews.llvm.org/D28445 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28445: [Analyzer] Extend taint propagation and checking
vlad.tsyrklevich added a comment. In https://reviews.llvm.org/D28445#694906, @zaks.anna wrote: > @vlad.tsyrklevich, > > Do you have commit access or should we commit on your behalf? You should commit on my behalf. https://reviews.llvm.org/D28445 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30720: [include-fixer] Add fuzzy SymbolIndex, where identifier needn't match exactly.
sammccall created this revision. Herald added a subscriber: mgorny. Add fuzzy SymbolIndex, where identifier needn't match exactly. The purpose for this is global autocomplete in clangd. The query will be a partial identifier up to the cursor, and the results will be suggestions. It's in include-fixer because: - it handles SymbolInfos, actually SymbolIndex is exactly the right interface - it's a good harness for lit testing the fuzzy YAML index - (Laziness: we can't unit test clangd until reorganizing with a tool/ dir) Other questionable choices: - FuzzySymbolIndex, which just refines the contract of SymbolIndex. This is an interface to allow extension to large monorepos (*cough*) - an always-true safety check that Identifier == Name is removed from SymbolIndexManager, as it's not true for fuzzy matching - exposing -db=fuzzyYaml from include-fixer is not a very useful feature, and a non-orthogonal ui (fuzziness vs data source). -db=fixed is similar though. https://reviews.llvm.org/D30720 Files: include-fixer/CMakeLists.txt include-fixer/FuzzySymbolIndex.cpp include-fixer/FuzzySymbolIndex.h include-fixer/SymbolIndexManager.cpp include-fixer/tool/ClangIncludeFixer.cpp test/include-fixer/Inputs/fake_yaml_db.yaml test/include-fixer/yaml_fuzzy.cpp unittests/include-fixer/CMakeLists.txt unittests/include-fixer/FuzzySymbolIndexTests.cpp Index: unittests/include-fixer/FuzzySymbolIndexTests.cpp === --- /dev/null +++ unittests/include-fixer/FuzzySymbolIndexTests.cpp @@ -0,0 +1,61 @@ +//===-- FuzzySymbolIndexTests.cpp - Fuzzy symbol index unit tests -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "FuzzySymbolIndex.h" +#include "gmock/gmock.h" +#include "llvm/Support/Regex.h" +#include "gtest/gtest.h" + +using testing::ElementsAre; +using testing::Not; + +namespace clang { +namespace include_fixer { +namespace { + +TEST(FuzzySymbolIndexTest, Tokenize) { + EXPECT_THAT(FuzzySymbolIndex::tokenize("URLHandlerCallback"), + ElementsAre("url", "handler", "callback")); + EXPECT_THAT(FuzzySymbolIndex::tokenize("snake_case11"), + ElementsAre("snake", "case", "11")); + EXPECT_THAT(FuzzySymbolIndex::tokenize("__$42!!BOB\nbob"), + ElementsAre("42", "bob", "bob")); +} + +MATCHER_P(MatchesSymbol, Identifier, "") { + llvm::Regex Pattern("^" + arg); + std::string err; + if (!Pattern.isValid(err)) { +*result_listener << "invalid regex: " << err; +return false; + } + auto Tokens = FuzzySymbolIndex::tokenize(Identifier); + std::string Target = llvm::join(Tokens.begin(), Tokens.end(), " "); + *result_listener << "matching against '" << Target << "'"; + return llvm::Regex("^" + arg).match(Target); +} + +TEST(FuzzySymbolIndexTest, QueryRegexp) { + auto QueryRegexp = [](const std::string &query) { +return FuzzySymbolIndex::queryRegexp(FuzzySymbolIndex::tokenize(query)); + }; + EXPECT_THAT(QueryRegexp("uhc"), MatchesSymbol("URLHandlerCallback")); + EXPECT_THAT(QueryRegexp("urhaca"), MatchesSymbol("URLHandlerCallback")); + EXPECT_THAT(QueryRegexp("uhcb"), Not(MatchesSymbol("URLHandlerCallback"))) + << "Non-prefix"; + EXPECT_THAT(QueryRegexp("uc"), Not(MatchesSymbol("URLHandlerCallback"))) + << "Skip token"; + + EXPECT_THAT(QueryRegexp("uptr"), MatchesSymbol("unique_ptr")); + EXPECT_THAT(QueryRegexp("UniP"), MatchesSymbol("unique_ptr")); +} + +} // namespace +} // namespace include_fixer +} // namespace clang Index: unittests/include-fixer/CMakeLists.txt === --- unittests/include-fixer/CMakeLists.txt +++ unittests/include-fixer/CMakeLists.txt @@ -13,6 +13,7 @@ add_extra_unittest(IncludeFixerTests IncludeFixerTest.cpp + FuzzySymbolIndexTests.cpp ) target_link_libraries(IncludeFixerTests Index: test/include-fixer/yaml_fuzzy.cpp === --- /dev/null +++ test/include-fixer/yaml_fuzzy.cpp @@ -0,0 +1,9 @@ +// RUN: sed -e 's#//.*$##' %s > %t.cpp +// RUN: clang-include-fixer -db=fuzzyYaml -input=%p/Inputs/fake_yaml_db.yaml %t.cpp -- +// RUN: FileCheck %s -input-file=%t.cpp + +// include-fixer will add the include, but doesn't complete the symbol. +// CHECK: #include "foobar.h" +// CHECK: fba f; + +b::a::fba f; Index: test/include-fixer/Inputs/fake_yaml_db.yaml === --- test/include-fixer/Inputs/fake_yaml_db.yaml +++ test/include-fixer/Inputs/fake_yaml_db.yaml @@ -11,6 +11,18 @@ Seen:1 Used:0 --- +Name: foo_bar +Contexts: + - ContextType: Namespace +ContextName: a + - ContextType: Namespace
r297227 - [AArch64] Vulcan is now ThunderXT99
Author: joel_k_jones Date: Tue Mar 7 15:24:53 2017 New Revision: 297227 URL: http://llvm.org/viewvc/llvm-project?rev=297227&view=rev Log: [AArch64] Vulcan is now ThunderXT99 Broadcom Vulcan is now Cavium ThunderX2T99. LLVM Bugzilla: http://bugs.llvm.org/show_bug.cgi?id=32113 Corresponding LLVM change: https://reviews.llvm.org/rL297190 Changes to clang to support the change. Patch by Joel Jones Modified: cfe/trunk/test/Driver/aarch64-cpus.c cfe/trunk/test/Frontend/aarch64-target-cpu.c cfe/trunk/test/Preprocessor/aarch64-target-features.c Modified: cfe/trunk/test/Driver/aarch64-cpus.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/aarch64-cpus.c?rev=297227&r1=297226&r2=297227&view=diff == --- cfe/trunk/test/Driver/aarch64-cpus.c (original) +++ cfe/trunk/test/Driver/aarch64-cpus.c Tue Mar 7 15:24:53 2017 @@ -154,23 +154,23 @@ // RUN: %clang -target arm64 -mlittle-endian -mtune=kryo -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-KRYO %s // ARM64-KRYO: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "kryo" -// RUN: %clang -target aarch64 -mcpu=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN %s -// RUN: %clang -target aarch64 -mlittle-endian -mcpu=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN %s -// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN %s -// RUN: %clang -target aarch64 -mtune=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN-TUNE %s -// RUN: %clang -target aarch64 -mlittle-endian -mtune=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN-TUNE %s -// RUN: %clang -target aarch64_be -mlittle-endian -mtune=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN-TUNE %s -// VULCAN: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "vulcan" "-target-feature" "+v8.1a" -// VULCAN-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "vulcan" -// VULCAN-TUNE-NOT: +v8.1a - -// RUN: %clang -target arm64 -mcpu=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-VULCAN %s -// RUN: %clang -target arm64 -mlittle-endian -mcpu=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-VULCAN %s -// RUN: %clang -target arm64 -mtune=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-VULCAN-TUNE %s -// RUN: %clang -target arm64 -mlittle-endian -mtune=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-VULCAN-TUNE %s -// ARM64-VULCAN: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "vulcan" "-target-feature" "+v8.1a" -// ARM64-VULCAN-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "vulcan" -// ARM64-VULCAN-TUNE-NOT: +v8.1a +// RUN: %clang -target aarch64 -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99 %s +// RUN: %clang -target aarch64 -mlittle-endian -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99 %s +// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99 %s +// RUN: %clang -target aarch64 -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-TUNE %s +// RUN: %clang -target aarch64 -mlittle-endian -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-TUNE %s +// RUN: %clang -target aarch64_be -mlittle-endian -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-TUNE %s +// THUNDERX2T99: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "thunderx2t99" "-target-feature" "+v8.1a" +// THUNDERX2T99-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "thunderx2t99" +// THUNDERX2T99-TUNE-NOT: +v8.1a + +// RUN: %clang -target arm64 -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-THUNDERX2T99 %s +// RUN: %clang -target arm64 -mlittle-endian -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-THUNDERX2T99 %s +// RUN: %clang -target arm64 -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-THUNDERX2T99-TUNE %s +// RUN: %clang -target arm64 -mlittle-endian -mtune=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-THUNDERX2T99-TUNE %s +// ARM64-THUNDERX2T99: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "thunderx2t99" "-target-feature" "+v8.1a" +// ARM64-THUNDERX2T99-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "thunderx2t99" +// ARM64-THUNDERX2T99-TUNE-NOT: +v8.1a // RUN: %clang -target aarch64_be -### -c %s 2>&1 | FileCheck -check-prefix=GENERIC-BE %s // RUN: %clang -target aarch64 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=GENERIC-BE %s @@ -241,21 +241,21 @@ // RUN: %clang -target aarch64_be -mbig-endian -mtune=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=M3-BE %s // M3-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "exynos-m3" -// RUN: %clang -target aarch64_be -mcpu=vulcan -### -c %s 2>&1 | FileCheck -check-prefix=VULCAN-BE %s -// RUN: %clang -target aarch64
r297148 - [clang-format] Followup of D30646 - unbreak the build
Author: abpostelnicu Date: Tue Mar 7 09:20:31 2017 New Revision: 297148 URL: http://llvm.org/viewvc/llvm-project?rev=297148&view=rev Log: [clang-format] Followup of D30646 - unbreak the build Modified: cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=297148&r1=297147&r2=297148&view=diff == --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Tue Mar 7 09:20:31 2017 @@ -5326,8 +5326,8 @@ TEST_F(FormatTest, BreaksLongDeclaration "aaa>>\n" "aa);"); - verifyFormat("template // Templates on own line.\n" - "static int // Some comment.\n" + verifyFormat("template // Templates on own line.\n" + "static int// Some comment.\n" "MyFunction(int a);", getLLVMStyle()); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297143 - [clang-format] Fixed indent issue when adding a comment at the end of a return type in named function declaration.
Author: abpostelnicu Date: Tue Mar 7 08:48:02 2017 New Revision: 297143 URL: http://llvm.org/viewvc/llvm-project?rev=297143&view=rev Log: [clang-format] Fixed indent issue when adding a comment at the end of a return type in named function declaration. Differential Revision: https://reviews.llvm.org/D30646 Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/unittests/Format/FormatTest.cpp Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=297143&r1=297142&r2=297143&view=diff == --- cfe/trunk/lib/Format/TokenAnnotator.cpp (original) +++ cfe/trunk/lib/Format/TokenAnnotator.cpp Tue Mar 7 08:48:02 2017 @@ -1166,9 +1166,9 @@ private: return false; // Skip "const" as it does not have an influence on whether this is a name. -FormatToken *PreviousNotConst = Tok.Previous; +FormatToken *PreviousNotConst = Tok.getPreviousNonComment(); while (PreviousNotConst && PreviousNotConst->is(tok::kw_const)) - PreviousNotConst = PreviousNotConst->Previous; + PreviousNotConst = PreviousNotConst->getPreviousNonComment(); if (!PreviousNotConst) return false; Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=297143&r1=297142&r2=297143&view=diff == --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Tue Mar 7 08:48:02 2017 @@ -5325,6 +5325,11 @@ TEST_F(FormatTest, BreaksLongDeclaration "vector>\n" "aa);"); + + verifyFormat("template // Templates on own line.\n" + "static int // Some comment.\n" + "MyFunction(int a);", + getLLVMStyle()); } TEST_F(FormatTest, FormatsArrays) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30700: [Driver] Always add arch-specific-subdir to -rpath
pirama added a comment. In https://reviews.llvm.org/D30700#694511, @rnk wrote: > I was thinking `-f[no-]compiler-rt-rpath` or something, but openmp is not > part of compiler-rt. Name recommendations welcome. \ Maybe `-f[no-]rtlib-add-rpath`? > We might also want to reconsider the default setting. I also feel defaulting to not adding rpath makes sense. https://reviews.llvm.org/D30700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30700: [Driver] Always add arch-specific-subdir to -rpath
rnk added a comment. Both suggestions sound good to me. Thanks! https://reviews.llvm.org/D30700 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30593: Add correct "-isystem"/"-isysroot" warning handling to static analysis' BugReporter.
dcoughlin added a comment. Kevin, would you be willing to file a PR on https://bugs.llvm.org with the 9 false positives you are seeing? This will help us suppress them for users who don't use 'suppress-c++-stdlib'. Repository: rL LLVM https://reviews.llvm.org/D30593 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30166: Honor __unaligned in codegen for declarations and expressions
rnk accepted this revision. rnk added a comment. Looks good! Sorry for the delay, I was out last week. https://reviews.llvm.org/D30166 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r297246 - [ODRHash] Hash typedefs and usings statements in classes.
Author: rtrieu Date: Tue Mar 7 18:13:19 2017 New Revision: 297246 URL: http://llvm.org/viewvc/llvm-project?rev=297246&view=rev Log: [ODRHash] Hash typedefs and usings statements in classes. Modified: cfe/trunk/lib/AST/ODRHash.cpp cfe/trunk/test/Modules/odr_hash.cpp Modified: cfe/trunk/lib/AST/ODRHash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHash.cpp?rev=297246&r1=297245&r2=297246&view=diff == --- cfe/trunk/lib/AST/ODRHash.cpp (original) +++ cfe/trunk/lib/AST/ODRHash.cpp Tue Mar 7 18:13:19 2017 @@ -211,6 +211,20 @@ public: Inherited::VisitCXXMethodDecl(D); } + + void VisitTypedefNameDecl(const TypedefNameDecl *D) { +AddQualType(D->getUnderlyingType()); + +Inherited::VisitTypedefNameDecl(D); + } + + void VisitTypedefDecl(const TypedefDecl *D) { +Inherited::VisitTypedefDecl(D); + } + + void VisitTypeAliasDecl(const TypeAliasDecl *D) { +Inherited::VisitTypeAliasDecl(D); + } }; // Only allow a small portion of Decl's to be processed. Remove this once @@ -226,6 +240,8 @@ bool ODRHash::isWhitelistedDecl(const De case Decl::CXXMethod: case Decl::Field: case Decl::StaticAssert: +case Decl::TypeAlias: +case Decl::Typedef: return true; } } @@ -313,6 +329,7 @@ public: void VisitTypedefType(const TypedefType *T) { AddDecl(T->getDecl()); +Hash.AddQualType(T->getDecl()->getUnderlyingType()); VisitType(T); } }; Modified: cfe/trunk/test/Modules/odr_hash.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=297246&r1=297245&r2=297246&view=diff == --- cfe/trunk/test/Modules/odr_hash.cpp (original) +++ cfe/trunk/test/Modules/odr_hash.cpp Tue Mar 7 18:13:19 2017 @@ -430,6 +430,99 @@ struct NestedNamespaceSpecifier {}; #endif } // namespace SelfReference +namespace TypeDef { +#if defined(FIRST) +struct S1 { + typedef int a; +}; +#elif defined(SECOND) +struct S1 { + typedef double a; +}; +#else +S1 s1; +// expected-error@first.h:* {{'TypeDef::S1::a' from module 'FirstModule' is not present in definition of 'TypeDef::S1' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'a' does not match}} +#endif + +#if defined(FIRST) +struct S2 { + typedef int a; +}; +#elif defined(SECOND) +struct S2 { + typedef int b; +}; +#else +S2 s2; +// expected-error@first.h:* {{'TypeDef::S2::a' from module 'FirstModule' is not present in definition of 'TypeDef::S2' in module 'SecondModule'}} +// expected-note@second.h:* {{definition has no member 'a'}} +#endif + +#if defined(FIRST) +typedef int T; +struct S3 { + typedef T a; +}; +#elif defined(SECOND) +typedef double T; +struct S3 { + typedef T a; +}; +#else +S3 s3; +// expected-error@first.h:* {{'TypeDef::S3::a' from module 'FirstModule' is not present in definition of 'TypeDef::S3' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'a' does not match}} +#endif +} // namespace TypeDef + +namespace Using { +#if defined(FIRST) +struct S1 { + using a = int; +}; +#elif defined(SECOND) +struct S1 { + using a = double; +}; +#else +S1 s1; +// expected-error@first.h:* {{'Using::S1::a' from module 'FirstModule' is not present in definition of 'Using::S1' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'a' does not match}} +#endif + +#if defined(FIRST) +struct S2 { + using a = int; +}; +#elif defined(SECOND) +struct S2 { + using b = int; +}; +#else +S2 s2; +// expected-error@first.h:* {{'Using::S2::a' from module 'FirstModule' is not present in definition of 'Using::S2' in module 'SecondModule'}} +// expected-note@second.h:* {{definition has no member 'a'}} +#endif + +#if defined(FIRST) +typedef int T; +struct S3 { + using a = T; +}; +#elif defined(SECOND) +typedef double T; +struct S3 { + using a = T; +}; +#else +S3 s3; +// expected-error@first.h:* {{'Using::S3::a' from module 'FirstModule' is not present in definition of 'Using::S3' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'a' does not match}} +#endif +} // namespace Using + + // Interesting cases that should not cause errors. struct S should not error // while struct T should error at the access specifier mismatch at the end. namespace AllDecls { @@ -460,6 +553,9 @@ struct S { inline void inline_method() {} void volatile_method() volatile {} void const_method() const {} + + typedef int typedef_int; + using using_int = int; }; #elif defined(SECOND) typedef int INT; @@ -488,6 +584,9 @@ struct S { inline void inline_method() {} void volatile_method() volatile {} void const_method() const {} + + typedef int typedef_int; + using using_int = int; }; #else S *s; @@ -521,6 +620,9 @@ struct T { void volatile_method() volatile {} void const_method() const {} + typedef int typedef_int; + usi
[PATCH] D30729: [ubsan] Skip range checks for width-limited values
vsk created this revision. UBSan can check that scalar loads provide in-range values. When we load a value from a bitfield, we know that the range of the value is constrained by the bitfield's width. This patch teaches UBSan how to use that information to skip emitting some range checks. This depends on / is a follow-up to: https://reviews.llvm.org/D30423 https://reviews.llvm.org/D30729 Files: lib/CodeGen/CGExpr.cpp lib/CodeGen/CodeGenFunction.h test/CodeGenCXX/ubsan-bitfields.cpp Index: test/CodeGenCXX/ubsan-bitfields.cpp === --- test/CodeGenCXX/ubsan-bitfields.cpp +++ test/CodeGenCXX/ubsan-bitfields.cpp @@ -7,7 +7,9 @@ }; struct S { - E e1 : 10; + E e1 : 10; //< Wide enough for the unsigned range check. + E e2 : 2; //< Still wide enough, 3 < 2^2. + E e3 : 1; //< Not wide enough, 3 > 2^1. }; // CHECK-LABEL: define i32 @_Z4loadP1S @@ -19,3 +21,65 @@ // CHECK: call void @__ubsan_handle_load_invalid_value return s->e1; } + +// CHECK-LABEL: define i32 @_Z5load2P1S +E load2(S *s) { + // CHECK: [[LOAD:%.*]] = load i16, i16* {{.*}} + // CHECK: [[LSHR:%.*]] = lshr i16 [[LOAD]], 10 + // CHECK: [[CLEAR:%.*]] = and i16 [[LSHR]], 3 + // CHECK: [[CAST:%.*]] = zext i16 [[CLEAR]] to i32 + // CHECK: icmp ule i32 [[CAST]], 3, !nosanitize + // CHECK: call void @__ubsan_handle_load_invalid_value + return s->e2; +} + +// CHECK-LABEL: define i32 @_Z5load3P1S +E load3(S *s) { + // CHECK-NOT: !nosanitize + return s->e3; +} + +enum E2 { + x = -3, + y = 3 +}; + +struct S2 { + E2 e1 : 4; //< Wide enough for signed range checks. + E2 e2 : 3; //< Still wide enough, -3 > -2^2 and 3 < 2^2. + E2 e3 : 2; //< Not wide enough, -3 < -2^1. +}; + +// CHECK-LABEL: define i32 @_Z5load4P2S2 +E2 load4(S2 *s) { + // CHECK: [[LOAD:%.*]] = load i16, i16* {{.*}} + // CHECK: [[SHL:%.*]] = shl i16 [[LOAD]], 12 + // CHECK: [[ASHR:%.*]] = ashr i16 [[SHL]], 12 + // CHECK: [[CAST:%.*]] = sext i16 [[ASHR]] to i32 + // CHECK: [[UPPER_BOUND:%.*]] = icmp sle i32 [[CAST]], 3, !nosanitize + // CHECK: [[LOWER_BOUND:%.*]] = icmp sge i32 [[CAST]], -4, !nosanitize + // CHECK: [[BOUND:%.*]] = and i1 [[UPPER_BOUND]], [[LOWER_BOUND]], !nosanitize + // CHECK: br i1 [[BOUND]], {{.*}}, !nosanitize + // CHECK: call void @__ubsan_handle_load_invalid_value + return s->e1; +} + +// CHECK-LABEL: define i32 @_Z5load5P2S2 +E2 load5(S2 *s) { + // CHECK: [[LOAD:%.*]] = load i16, i16* {{.*}} + // CHECK: [[SHL:%.*]] = shl i16 [[LOAD]], 9 + // CHECK: [[ASHR:%.*]] = ashr i16 [[SHL]], 13 + // CHECK: [[CAST:%.*]] = sext i16 [[ASHR]] to i32 + // CHECK: [[UPPER_BOUND:%.*]] = icmp sle i32 [[CAST]], 3, !nosanitize + // CHECK: [[LOWER_BOUND:%.*]] = icmp sge i32 [[CAST]], -4, !nosanitize + // CHECK: [[BOUND:%.*]] = and i1 [[UPPER_BOUND]], [[LOWER_BOUND]], !nosanitize + // CHECK: br i1 [[BOUND]], {{.*}}, !nosanitize + // CHECK: call void @__ubsan_handle_load_invalid_value + return s->e2; +} + +// CHECK-LABEL: define i32 @_Z5load6P2S2 +E2 load6(S2 *s) { + // CHECK-NOT: !nosanitize + return s->e3; +} Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -2892,11 +2892,12 @@ llvm::Value *EmitFromMemory(llvm::Value *Value, QualType Ty); /// Check if the scalar \p Value is within the valid range for the given - /// type \p Ty. + /// type \p Ty. If \p BitWidth is provided, it must be the bit width of the + /// storage for the scalar. /// - /// Returns true if a check is needed (even if the range is unknown). - bool EmitScalarRangeCheck(llvm::Value *Value, QualType Ty, -SourceLocation Loc); + /// Returns true if range metadata for the scalar should be dropped. + bool EmitScalarRangeCheck(llvm::Value *Value, QualType Ty, SourceLocation Loc, +Optional BitWidth = None); /// EmitLoadOfScalar - Load a scalar value from an address, taking /// care to appropriately convert from the memory representation to Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -1302,7 +1302,8 @@ } bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty, - SourceLocation Loc) { + SourceLocation Loc, + Optional BitWidth) { bool HasBoolCheck = SanOpts.has(SanitizerKind::Bool); bool HasEnumCheck = SanOpts.has(SanitizerKind::Enum); if (!HasBoolCheck && !HasEnumCheck) @@ -1319,9 +1320,32 @@ if (!getRangeForType(*this, Ty, Min, End, /*StrictEnums=*/true, IsBool)) return true; + --End; + if (BitWidth) { +if (!Min) { + // If End > MaxValueForWidth, then Value < End. Skip the range check. + auto MaxValueForWidth = +
[PATCH] D30729: [ubsan] Skip range checks for width-limited values
vsk updated this revision to Diff 90975. vsk added a comment. - Fix an incorrect comment on the field "e2" in struct S. We emit a check for it because 0b11 = -1 = 3. - Skip the range check on the field "e2" in struct S2, because the range of the bitfield is the same as the range clang infers for the enum. https://reviews.llvm.org/D30729 Files: lib/CodeGen/CGExpr.cpp lib/CodeGen/CodeGenFunction.h test/CodeGenCXX/ubsan-bitfields.cpp Index: test/CodeGenCXX/ubsan-bitfields.cpp === --- test/CodeGenCXX/ubsan-bitfields.cpp +++ test/CodeGenCXX/ubsan-bitfields.cpp @@ -7,7 +7,9 @@ }; struct S { - E e1 : 10; + E e1 : 10; //< Wide enough for the unsigned range check. + E e2 : 2; //< Emit the check, since -1 = 3 = 0b11. + E e3 : 1; //< Skip the check. }; // CHECK-LABEL: define i32 @_Z4loadP1S @@ -19,3 +21,58 @@ // CHECK: call void @__ubsan_handle_load_invalid_value return s->e1; } + +// CHECK-LABEL: define i32 @_Z5load2P1S +E load2(S *s) { + // CHECK: [[LOAD:%.*]] = load i16, i16* {{.*}} + // CHECK: [[LSHR:%.*]] = lshr i16 [[LOAD]], 10 + // CHECK: [[CLEAR:%.*]] = and i16 [[LSHR]], 3 + // CHECK: [[CAST:%.*]] = zext i16 [[CLEAR]] to i32 + // CHECK: icmp ule i32 [[CAST]], 3, !nosanitize + // CHECK: call void @__ubsan_handle_load_invalid_value + return s->e2; +} + +// CHECK-LABEL: define i32 @_Z5load3P1S +E load3(S *s) { + // CHECK-NOT: !nosanitize + return s->e3; +} + +enum E2 { + x = -3, + y = 3 +}; + +struct S2 { + E2 e1 : 4; //< Wide enough for signed range checks. + E2 e2 : 3; //< Skip the check, since the range of the bitfield is the same + // as the range of the enum: [-4, 3]. + E2 e3 : 2; //< Still skip the check. +}; + +// CHECK-LABEL: define i32 @_Z5load4P2S2 +E2 load4(S2 *s) { + // CHECK: [[LOAD:%.*]] = load i16, i16* {{.*}} + // CHECK: [[SHL:%.*]] = shl i16 [[LOAD]], 12 + // CHECK: [[ASHR:%.*]] = ashr i16 [[SHL]], 12 + // CHECK: [[CAST:%.*]] = sext i16 [[ASHR]] to i32 + // CHECK: [[UPPER_BOUND:%.*]] = icmp sle i32 [[CAST]], 3, !nosanitize + // CHECK: [[LOWER_BOUND:%.*]] = icmp sge i32 [[CAST]], -4, !nosanitize + // CHECK: [[BOUND:%.*]] = and i1 [[UPPER_BOUND]], [[LOWER_BOUND]], !nosanitize + // CHECK: br i1 [[BOUND]], {{.*}}, !nosanitize + // CHECK: call void @__ubsan_handle_load_invalid_value + return s->e1; +} + +// CHECK-LABEL: define i32 @_Z5load5P2S2 +E2 load5(S2 *s) { + // CHECK-NOT: !nosanitize + return s->e2; +} + +// CHECK-LABEL: define i32 @_Z5load6P2S2 +E2 load6(S2 *s) { + // CHECK-NOT: !nosanitize + return s->e3; +} Index: lib/CodeGen/CodeGenFunction.h === --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -2892,11 +2892,12 @@ llvm::Value *EmitFromMemory(llvm::Value *Value, QualType Ty); /// Check if the scalar \p Value is within the valid range for the given - /// type \p Ty. + /// type \p Ty. If \p BitWidth is provided, it must be the bit width of the + /// storage for the scalar. /// - /// Returns true if a check is needed (even if the range is unknown). - bool EmitScalarRangeCheck(llvm::Value *Value, QualType Ty, -SourceLocation Loc); + /// Returns true if range metadata for the scalar should be dropped. + bool EmitScalarRangeCheck(llvm::Value *Value, QualType Ty, SourceLocation Loc, +Optional BitWidth = None); /// EmitLoadOfScalar - Load a scalar value from an address, taking /// care to appropriately convert from the memory representation to Index: lib/CodeGen/CGExpr.cpp === --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -1302,7 +1302,8 @@ } bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty, - SourceLocation Loc) { + SourceLocation Loc, + Optional BitWidth) { bool HasBoolCheck = SanOpts.has(SanitizerKind::Bool); bool HasEnumCheck = SanOpts.has(SanitizerKind::Enum); if (!HasBoolCheck && !HasEnumCheck) @@ -1319,9 +1320,32 @@ if (!getRangeForType(*this, Ty, Min, End, /*StrictEnums=*/true, IsBool)) return true; + --End; + if (BitWidth) { +if (!Min) { + // If End > MaxValueForWidth, then Value < End. Skip the range check. + auto MaxValueForWidth = + llvm::APInt::getMaxValue(*BitWidth).zextOrSelf(End.getBitWidth()); + if (End.ugt(MaxValueForWidth)) +return false; +} else { + assert(Min.eq(-(End + 1)) && + "The full range check assumes Min = -(End + 1)"); + assert(Ty->hasSignedIntegerRepresentation() && + "The full range check works on signed integers only"); + + // If Min <= MinValueForWidth, then Value >= Min. Since Min = -(End + 1), + // End >= MaxValueForWidth, and Value
[PATCH] D21279: Fix some issues in clang-format's AlignConsecutive modes
daphnediane added a comment. ping https://reviews.llvm.org/D21279 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D30423: [ubsan] Detect UB loads from bitfields
jroelofs accepted this revision. jroelofs added a comment. This revision is now accepted and ready to land. LGTM Comment at: test/CodeGenObjC/ubsan-bool.m:26 + // OBJC: [[ICMP:%.*]] = icmp ule i8 [[ASHR]], 1, !nosanitize + // OBJC: call void @__ubsan_handle_load_invalid_value + vsk wrote: > jroelofs wrote: > > vsk wrote: > > > arphaman wrote: > > > > Is it possible to avoid the check here since the bitfield is just one > > > > bit wide? > > > No, a user could do: > > > > > > ``` > > > struct S1 s; > > > s.b1 = 1; > > > if (s.b1 == 1) // evaluates to false, s.b1 is negative > > > ``` > > > > > > With this patch we get: > > > ``` > > > runtime error: load of value -1, which is not a valid value for type > > > 'BOOL' (aka 'signed char') > > > ``` > > What if BOOL is an `unsigned char`, or a `char` that's not signed? > Good point, we don't need to emit the range check if the bitfield is an > unsigned, 1-bit wide BOOL. Would you be OK with me tackling that in a > follow-up patch? No problem, sounds good to me. Comment at: test/CodeGenObjC/ubsan-bool.m:50 +// OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7 +// OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7 +// OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize hmmm. just occurred to me that this value is always going to be 0xff or 0x0, so it might be useful if there were also a frontend warning that complains about signed bitfield bools (maybe something useful for another patch). https://reviews.llvm.org/D30423 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits