Summary: | clang++ 3.7.1 gets Bus Errors during compilation on arm that has SCTLR bit[1]==1 (alignment required) | ||
---|---|---|---|
Product: | Base System | Reporter: | Mark Millard <marklmi26-fbsd> |
Component: | bin | Assignee: | freebsd-bugs (Nobody) <bugs> |
Status: | Closed Overcome By Events | ||
Severity: | Affects Many People | ||
Priority: | --- | ||
Version: | CURRENT | ||
Hardware: | arm | ||
OS: | Any |
Description
Mark Millard
2015-12-28 12:55:24 UTC
I forgot to include the asked-for stack backtrace and some related information: Program terminated with signal 10, Bus error. #0 0x00c404d0 in clang::DependentTemplateSpecializationType::DependentTemplateSpecializationType () [New Thread 22a18000 (LWP 100173/<unknown>)] (gdb) bt #0 0x00c404d0 in clang::DependentTemplateSpecializationType::DependentTemplateSpecializationType () #1 0x00d86634 in clang::ASTContext::getDependentTemplateSpecializationType () #2 0x00d865d8 in clang::ASTContext::getDependentTemplateSpecializationType () #3 0x00d862d4 in clang::ASTContext::getDependentTemplateSpecializationType () #4 0x00553b7c in clang::Sema::ActOnTypenameType () #5 0x0040cb68 in clang::Parser::TryAnnotateTypeOrScopeToken () #6 0x00471198 in $a.28 () #7 0x00471198 in $a.28 () (gdb) x/1i 0x00c404d0 0xc404d0 <_ZN5clang35DependentTemplateSpecializationTypeC2ENS_21ElaboratedTypeKeywordEPNS_19NestedNameSpecifierEPKNS_14IdentifierInfoEjPKNS_16TemplateArgumentENS_8QualTypeE+356>: vst1.64 {d16-d17}, [r4]! (gdb) info all-registers r0 0xbfbf9778 -1077962888 r1 0x22ac59c4 581720516 r2 0xc45ff8 12869624 r3 0x2 2 r4 0x22ac59ac 581720492 . . . I've submitted the compiler crash to llmv.org as: https://llvm.org/bugs/show_bug.cgi?id=25958 It is basically a duplicate by content of this submittal. Below is what llvm-org's James Molloy reports about needing -mno-unaligned-access when building clang and clang++ for use in a SCTLR bit[1]==1 context: From: bugzilla-daemon@llvm.org Subject: [Bug 25958] FreeBSD 11.0-CURRENT clang++ 3.7.1 gets Bus Errors during compilation on arm that has SCTLR bit[1]==1 (alignment required) Date: December 28, 2015 at 1:28:28 PM PST To: <markmi@dsl-only.net> James Molloy changed bug 25958 What Removed Added CC james.molloy@arm.com Comment # 2 on bug 25958 from James Molloy Hi Mark, Thanks for raising this. Before checking the specifics of what you found - did you compile Clang with -mno-unaligned-access? We will by default compile assuming SCTLR.A is 0. -mno-unaligned-access switches this assumption off and enables strict alignment mode. Cheers, James More notes: I've answered with the example compilation command for the specific clang source file, extracted from a script log of my build: I had used -mno-unaligned-access. I've added the following new information on llvm's bugzilla report. Basically alignas use can avoid the alignment problems but there are lots of places that would need it in order for clang++ to work overall for SCTLR bit[1]==1. The following change eliminates the specific Bus Error in clang and allows the 11 line program to compile on an rpi2 --but causes include/clang/AST/Type.h to pollute a namespace via <cstddef> use: # svnlite diff /usr/src/contrib/llvm/ Index: /usr/src/contrib/llvm/tools/clang/include/clang/AST/Type.h =================================================================== --- /usr/src/contrib/llvm/tools/clang/include/clang/AST/Type.h (revision 292858) +++ /usr/src/contrib/llvm/tools/clang/include/clang/AST/Type.h (working copy) @@ -14,6 +14,8 @@ #ifndef LLVM_CLANG_AST_TYPE_H #define LLVM_CLANG_AST_TYPE_H +#include <cstddef> // for std::max_align_t + #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateName.h" #include "clang/Basic/AddressSpaces.h" @@ -4336,7 +4338,7 @@ /// DependentTemplateSpecializationType - Represents a template /// specialization type whose template cannot be resolved, e.g. /// A<T>::template B<T> -class DependentTemplateSpecializationType : +class alignas(alignof(std::max_align_t)) DependentTemplateSpecializationType : public TypeWithKeyword, public llvm::FoldingSetNode { /// \brief The nested name specifier containing the qualifier. alignof(TemplateArgument) is not used because Types.h is used in contexts where TemplateArgument is an incomplete type and the notation would be rejected. The command that built a Type.o that worked was (from the script log of the build): --- Type.o --- /usr/bin/clang++ -target armv6--freebsd11.0-gnueabi -march=armv7a -mno-unaligned-access -target armv6-gnueabi-freebsd11.0 --sysroot=/usr/obj/clang/arm.armv6/usr/src/tmp -B/usr/local/arm-gnueabi-freebs d/bin/ --sysroot=/usr/obj/clang/arm.armv6/usr/src/tmp -B/usr/local/arm-gnueabi-freebsd/bin/ -O -pipe -mfloat-abi=softfp -I/usr/src/lib/clang/libclangast/../../../contrib/llvm/include -I/usr/src/lib/c lang/libclangast/../../../contrib/llvm/tools/clang/include -I/usr/src/lib/clang/libclangast/../../../contrib/llvm/tools/clang/lib/AST -I. -I/usr/src/lib/clang/libclangast/../../../contrib/llvm/../../l ib/clang/include -DLLVM_ON_UNIX -DLLVM_ON_FREEBSD -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -DCLANG_ENABLE_ARCMT -DCLANG_ENABLE_STATIC_ANALYZER -fno-strict-aliasing -DLLVM_DEFAULT_TARGET_TRIPLE=\ "armv6-gnueabi-freebsd11.0\" -DLLVM_HOST_TRIPLE=\"armv6-unknown-freebsd11.0\" -DDEFAULT_SYSROOT=\"\" -MD -MP -MF.depend.Type.o -MTType.o -Qunused-arguments -std=c++11 -fno-exceptions -fno-rtti -stdli b=libc++ -Wno-c++11-extensions -c /usr/src/lib/clang/libclangast/../../../contrib/llvm/tools/clang/lib/AST/Type.cpp -o Type.o So it used (in order): -target armv6--freebsd11.0-gnueabi -march=armv7a -mno-unaligned-access -target armv6-gnueabi-freebsd11.0 (The first -target is what I supplied, the 2nd is from the FreeBSD build environment.) STILL FAILS OVERALL HOWEVER. . . Unfortunately clang++ on the rpi2 with SCTLR bit[1]==1 dies for other c++ syntax when trying to build part of llvm (early in FreeBSD's buildworld): Program terminated with signal 10, Bus error. #0 0x00c43d28 in clang::ASTTemplateArgumentListInfo::initializeFrom () [New Thread 22a18000 (LWP 100079/<unknown>)] (gdb) bt #0 0x00c43d28 in clang::ASTTemplateArgumentListInfo::initializeFrom () #1 0x00c43f10 in clang::ASTTemplateKWAndArgsInfo::initializeFrom () #2 0x00cdc788 in clang::CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr () #3 0x00cdc99c in clang::CXXDependentScopeMemberExpr::Create () #4 0x00685384 in clang::Sema::ActOnDependentMemberExpr () #5 0x0068abec in clang::Sema::ActOnMemberAccessExpr () #6 0x0044a938 in clang::Parser::ParsePostfixExpressionSuffix () #7 0x00000000 in ?? () (gdb) x/i 0x00c43d28 0xc43d28 <_ZN5clang27ASTTemplateArgumentListInfo14initializeFromERKNS_24TemplateArgumentListInfoERbS4_S4_+396>: vst1.64 {d16-d17}, [r0]! (gdb) info all-regsisters Undefined info command: "all-regsisters". Try "help info". (gdb) info all-registers r0 0x234b96dc 592156380 . . . There are lots of places using "this + 1" and reinterpret_cast that therefore have the potential for a mis-matched alignment between the two types involved, just like the one I initially reported (some of the below might not be at risk, I've not inspected all the details of each): # grep "reinterpret_cast.*this" lib/*/* lib/AST/Decl.cpp: SourceLocation *StoredLocs = reinterpret_cast<SourceLocation *>(this + 1); lib/AST/Decl.cpp: *reinterpret_cast<SourceLocation *>(this + 1) = EndLoc; lib/AST/Decl.cpp: = reinterpret_cast<const SourceLocation *>(this + 1); lib/AST/Decl.cpp: *reinterpret_cast<const SourceLocation *>(this + 1)); lib/AST/DeclCXX.cpp: VarDecl **MyIndices = reinterpret_cast<VarDecl **> (this + 1); lib/AST/DeclOpenMP.cpp: Expr **Vars = reinterpret_cast<Expr **>(this + 1); lib/AST/DeclTemplate.cpp: void **TypesAndInfos = reinterpret_cast<void **>(this + 1); lib/AST/DeclTemplate.cpp: std::memcpy(reinterpret_cast<void*>(this + 1), Expansions, lib/AST/Expr.cpp: return reinterpret_cast<CXXBaseSpecifier**>(static_cast<Type*>(this)+1); lib/AST/Expr.cpp: Stmt *const *SubExprs = reinterpret_cast<Stmt *const *>(this + 1); lib/AST/Expr.cpp: Stmt *const *SubExprs = reinterpret_cast<Stmt *const *>(this + 1); lib/AST/Expr.cpp: Stmt *const *SubExprs = reinterpret_cast<Stmt *const *>(this + 1); lib/AST/Expr.cpp: begin = reinterpret_cast<Stmt **>(this + 1); lib/AST/ExprCXX.cpp: Stmt **StoredArgs = reinterpret_cast<Stmt **>(this + 1); lib/AST/ExprCXX.cpp: reinterpret_cast<Decl**>(this+1)); lib/AST/Stmt.cpp: Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1); lib/AST/Stmt.cpp: reinterpret_cast<char *>(const_cast<CapturedStmt *>(this)) lib/AST/Type.cpp: QualType *argSlot = reinterpret_cast<QualType*>(this+1); lib/AST/Type.cpp: = reinterpret_cast<TemplateArgument *>(this + 1); lib/AST/Type.cpp: TemplateArgument *Begin = reinterpret_cast<TemplateArgument *>(this + 1); lib/Basic/IdentifierTable.cpp: IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this+1); lib/Basic/IdentifierTable.cpp: return reinterpret_cast<keyword_iterator>(this+1); lib/CodeGen/CGCleanup.h: return reinterpret_cast<Handler*>(this+1); lib/CodeGen/CGCleanup.h: return reinterpret_cast<const Handler*>(this+1); lib/CodeGen/CGCleanup.h: return reinterpret_cast<llvm::Value**>(this+1); lib/CodeGen/CGCleanup.h: return reinterpret_cast<llvm::Value* const *>(this+1); lib/CodeGen/CGExprCXX.cpp: RValue *getPlacementArgs() { return reinterpret_cast<RValue*>(this+1); } lib/CodeGen/CGExprCXX.cpp: return reinterpret_cast<DominatingValue<RValue>::saved_type*>(this+1); lib/Sema/CodeCompleteConsumer.cpp: Chunk *StoredChunks = reinterpret_cast<Chunk *>(this + 1); But there is lots more use of reinterpret_cast where "this" is not involved that might also have problems. Compare: # grep -l "reinterpret_cast.*this" lib/*/* lib/AST/Decl.cpp lib/AST/DeclCXX.cpp lib/AST/DeclOpenMP.cpp lib/AST/DeclTemplate.cpp lib/AST/Expr.cpp lib/AST/ExprCXX.cpp lib/AST/Stmt.cpp lib/AST/Type.cpp lib/Basic/IdentifierTable.cpp lib/CodeGen/CGCleanup.h lib/CodeGen/CGExprCXX.cpp lib/Sema/CodeCompleteConsumer.cpp vs. # grep -l "reinterpret_cast" lib/*/* lib/AST/APValue.cpp lib/AST/ASTDiagnostic.cpp lib/AST/Decl.cpp lib/AST/DeclCXX.cpp lib/AST/DeclOpenMP.cpp lib/AST/DeclTemplate.cpp lib/AST/DeclarationName.cpp lib/AST/Expr.cpp lib/AST/ExprCXX.cpp lib/AST/ExprConstant.cpp lib/AST/ItaniumMangle.cpp lib/AST/NestedNameSpecifier.cpp lib/AST/ParentMap.cpp lib/AST/Stmt.cpp lib/AST/StmtIterator.cpp lib/AST/Type.cpp lib/AST/TypeLoc.cpp lib/Analysis/CFG.cpp lib/Basic/Diagnostic.cpp lib/Basic/FileManager.cpp lib/Basic/IdentifierTable.cpp lib/CodeGen/CGBlocks.h lib/CodeGen/CGCleanup.cpp lib/CodeGen/CGCleanup.h lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprCXX.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/MicrosoftCXXABI.cpp lib/Driver/MSVCToolChain.cpp lib/Driver/Tools.h lib/Format/Encoding.h lib/Frontend/CacheTokens.cpp lib/Frontend/DependencyFile.cpp lib/Frontend/TextDiagnostic.cpp lib/Lex/HeaderMap.cpp lib/Lex/LiteralSupport.cpp lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/ParseObjc.cpp lib/Parse/ParsePragma.cpp lib/Parse/ParseTentative.cpp lib/Parse/Parser.cpp lib/Rewrite/RewriteRope.cpp lib/Sema/CodeCompleteConsumer.cpp lib/Sema/IdentifierResolver.cpp lib/Sema/SemaCast.cpp lib/Sema/SemaCodeComplete.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaDeclObjC.cpp lib/Sema/SemaExprMember.cpp lib/Sema/SemaExprObjC.cpp lib/Sema/SemaInit.cpp lib/Sema/SemaLookup.cpp lib/Sema/SemaStmt.cpp lib/Sema/SemaStmtAsm.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriter.cpp I reported the following information on the llvm bugzilla: To get a quick handle on the size of the investigation effort for alignments of reinterpret_casts to pointer types in llvm/clang I've tried to get *approximations* of: A) count of reinterpret_cast's to pointer types that do not involve base types with "char" or "int8" text (on the same line). and B) How many files have such reinterpret_cast's. # pwd /usr/src/contrib/llvm # find -s . -exec grep -E "reinterpret_cast[ \t]*<[^>]*\*" {} \; | grep -v char | grep -v int8 | wc 789 3453 51918 # find -s . -exec grep -E "reinterpret_cast[ \t]*<[^>]*(char|int8)[^>]*\*" {} \; | wc 171 854 11326 (Some files may have a mix of both with and without char/int8.) # find -s . -exec grep -E "reinterpret_cast[ \t]*<[^>]*\*" {} \; -print | grep "^\.\/" | wc 264 264 10517 # find -s . -exec grep -E "reinterpret_cast[ \t]*<[^>]*(char|int8)[^>]*\*" {} \; -print | grep "^\.\/" | wc 71 71 2781 (So 264-71==193 to 264 files.) And also: C) How many reinterpret_cast's directly involve the text "this" (on the same line): # find -s . -exec grep -E "reinterpret_cast[ \t]*<[^>]*\*.*this" {} \; | grep -v char | grep -v int8 | wc 132 739 8443 D) How many files is that? # find -s . -exec grep -E "reinterpret_cast[ \t]*<[^>]*\*.*this" {} \; -print | grep "^\.\/" | wc 47 47 1914 # find -s . -exec grep -E "reinterpret_cast[ \t]*<[^>]*(char|int8)[^>]*\*.*this" {} \; -print | grep "^\.\/" | wc 5 5 185 (So 47-5==42 to 47 files.) E) How many reinterpret_cast's do not mention "this", "char", or "int8" (on the same line): # find -s . -exec grep -E "reinterpret_cast[ \t]*<[^>]*\*" {} \; | grep -v this | grep -v char | grep -v int8 | wc 647 2663 42647 This is the majority of the reinterpret_cast's, by far. It looks non-trivial to find and adjust the llvm/clang source so that all the places that do not currently deal with proper alignment for SCTLR bit[1]==1 contexts instead do so. So it is not likely to be happen time soon, much less finish any time soon. This will limit FreeBSD 11.0's "self hosting on arm" c++ support via the system/clang++ tool chain greatly based on the CTLR bit[1]==1 status: cross builds required from a host not requiring alignment, such as from amd64. (Once some other C++ tool chain is in place on an arm more native work may then be possible.) The C part of clang does appear to compile okay for buildkernel use in the SCTRL bit[1]==1 context. So far all the misalignments have happened in compiling-c++ contexts, which is involved for buildworld and for building many ports. llvm.org's Bugzilla reports that clang trunk has been fixed and clang 3.8 will contain the fixes: James Molloy changed bug 25958 What Removed Added Status NEW RESOLVED Resolution --- FIXED Comment # 8 on bug 25958 from James Molloy Hi Mark, Thanks for your detailed investigation. I can confirm that this is fixed on trunk and therefore will be fixed for LLVM 3.8. The fixes were done for SPARC, which requires strict accesses much as ARM does with SCTLR=1. There was a sequence of commits by James Knight that fixed these, but an example is http://reviews.llvm.org/rL242554 . The fixes were in a similar vein to yours, but required changes in fewer places and there were a few more sticky issues to solve too. I'll CC James here in case he wants to comment on the current state of the clang codebase for self-hosting in a strict alignment environment. Cheers, James Clang 3.8.0 does not have this problem. And also recently 11.0 enabled more misalignments: SCTLR bit[1]==1 is no longer in use. Clang 3.8.0 was in use for some time before this change and was not getting bus errors. 3.7.1 is no longer relevant for 11.0. |