Import Clang 3.8.1+ r280599.

This commit is contained in:
joerg 2016-09-03 23:11:41 +00:00
parent b75c02b32e
commit e2a06b5df1
10 changed files with 328 additions and 94 deletions

View File

@ -16,7 +16,7 @@ frontend, part of the LLVM Compiler Infrastructure, release 3.8. Here we
describe the status of Clang in some detail, including major
improvements from the previous release and new feature work. For the
general LLVM release notes, see `the LLVM
documentation <http://llvm.org/docs/ReleaseNotes.html>`_. All LLVM
documentation <../../../docs/ReleaseNotes.html>`_. All LLVM
releases may be downloaded from the `LLVM releases web
site <http://llvm.org/releases/>`_.
@ -33,11 +33,6 @@ here. Generic improvements to Clang as a whole or to its underlying
infrastructure are described first, followed by language-specific
sections with improvements to Clang's support for those languages.
Major New Features
------------------
- Feature1...
Improvements to Clang's diagnostics
-----------------------------------
@ -49,8 +44,6 @@ about them. The improvements since the 3.7 release include:
choose to enable only a subset of these warnings. ``-Wno-microsoft`` still
disables all these warnings, and ``-Wmicrosoft`` still enables them all.
- ...
New Compiler Flags
------------------
@ -71,16 +64,89 @@ debugger. Clang supports tuning for three debuggers, as follows.
Specifying ``-g`` without a tuning option will use a target-dependent default.
The new ``-fstrict-vtable-pointers`` flag enables better devirtualization
support (experimental).
New Pragmas in Clang
-----------------------
Clang now supports the ...
Alignment
---------
Clang has gotten better at passing down strict type alignment information to LLVM,
and several targets have gotten better at taking advantage of that information.
Windows Support
---------------
Dereferencing a pointer that is not adequately aligned for its type is undefined
behavior. It may crash on target architectures that strictly enforce alignment, but
even on architectures that do not, frequent use of unaligned pointers may hurt
the performance of the generated code.
Clang's support for building native Windows programs ...
If you find yourself fixing a bug involving an inadequately aligned pointer, you
have several options.
The best option, when practical, is to increase the alignment of the memory.
For example, this array is not guaranteed to be sufficiently aligned to store
a pointer value:
.. code-block:: c
char buffer[sizeof(const char*)];
Writing a pointer directly into it violates C's alignment rules:
.. code-block:: c
((const char**) buffer)[0] = "Hello, world!\n";
But you can use alignment attributes to increase the required alignment:
.. code-block:: c
__attribute__((aligned(__alignof__(const char*))))
char buffer[sizeof(const char*)];
When that's not practical, you can instead reduce the alignment requirements
of the pointer. If the pointer is to a struct that represents that layout of a
serialized structure, consider making that struct packed; this will remove any
implicit internal padding that the compiler might add to the struct and
reduce its alignment requirement to 1.
.. code-block:: c
struct file_header {
uint16_t magic_number;
uint16_t format_version;
uint16_t num_entries;
} __attribute__((packed));
You may also override the default alignment assumptions of a pointer by
using a typedef with explicit alignment:
.. code-block:: c
typedef const char *unaligned_char_ptr __attribute__((aligned(1)));
((unaligned_char_ptr*) buffer)[0] = "Hello, world!\n";
The final option is to copy the memory into something that is properly
aligned. Be aware, however, that Clang will assume that pointers are
properly aligned for their type when you pass them to a library function
like memcpy. For example, this code will assume that the source and
destination pointers are both properly aligned for an int:
.. code-block:: c
void copy_int_array(int *dest, const int *src, size_t num) {
memcpy(dest, src, num * sizeof(int));
}
You may explicitly disable this assumption by casting the argument to a
less-aligned pointer type:
.. code-block:: c
void copy_unaligned_int_array(int *dest, const int *src, size_t num) {
memcpy((char*) dest, (const char*) src, num * sizeof(int));
}
Clang promises not to look through the explicit cast when inferring the
alignment of this memcpy.
C Language Changes in Clang
@ -117,30 +183,6 @@ Now, Clang is able to selectively use C's type conversion rules during overload
resolution in C, which allows the above example to compile (albeit potentially
with a warning about an implicit conversion from ``int*`` to ``char*``).
...
C11 Feature Support
^^^^^^^^^^^^^^^^^^^
...
C++ Language Changes in Clang
-----------------------------
- ...
C++11 Feature Support
^^^^^^^^^^^^^^^^^^^^^
...
Objective-C Language Changes in Clang
-------------------------------------
...
OpenCL C Language Changes in Clang
----------------------------------
@ -180,10 +222,10 @@ Several additional features/bugfixes have been added to the previous standards:
- Improved diagnostics for function pointers.
OpenMP Support in Clang
---------------------
-----------------------
OpenMP 3.1 is fully supported and is enabled by default with -fopenmp
which now uses the clang OpenMP library instead of the GCC OpenMP library.
OpenMP 3.1 is fully supported and is enabled by default with ``-fopenmp``
which now uses the Clang OpenMP library instead of the GCC OpenMP library.
The runtime can be built in-tree.
In addition to OpenMP 3.1, several important elements of the OpenMP 4.0/4.5
@ -214,7 +256,7 @@ Clang has experimental support for end-to-end CUDA compilation now:
pipelines, links device-side code with appropriate CUDA bitcode and produces
single object file with host and GPU code.
- Implemented target attribute-based function overloading which allows clang to
- Implemented target attribute-based function overloading which allows Clang to
compile CUDA sources without splitting them into separate host/device TUs.
Internal API Changes
@ -271,17 +313,11 @@ recordDecl() previously matched AST nodes of type CXXRecordDecl, but now
matches AST nodes of type RecordDecl. If a CXXRecordDecl is required, use the
cxxRecordDecl() matcher instead.
...
libclang
--------
...
Static Analyzer
---------------
The scan-build and scan-view tools will now be installed with clang. Use these
The scan-build and scan-view tools will now be installed with Clang. Use these
tools to run the static analyzer on projects and view the produced results.
Static analysis of C++ lambdas has been greatly improved, including
@ -302,25 +338,76 @@ Several new checks were added:
the following command to scan-build:
``-enable-checker optin.osx.cocoa.localizability``.
Core Analysis Improvements
==========================
- ...
Clang-tidy
----------
New Issues Found
================
New checks have been added to clang-tidy:
- ...
* Checks enforcing certain rules of the `CERT Secure Coding Standards
<https://www.securecoding.cert.org/confluence/display/seccode/SEI+CERT+Coding+Standards>`_:
Python Binding Changes
----------------------
* `cert-dcl03-c <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cert-dcl03-c.html>`_
* `cert-dcl50-cpp <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cert-dcl50-cpp.html>`_
* `cert-err52-cpp <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cert-err52-cpp.html>`_
* `cert-err58-cpp <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cert-err58-cpp.html>`_
* `cert-err60-cpp <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cert-err60-cpp.html>`_
* `cert-err61-cpp <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cert-err61-cpp.html>`_
* `cert-fio38-c <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cert-fio38-c.html>`_
* `cert-oop11-cpp <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cert-oop11-cpp.html>`_
The following methods have been added:
* Checks supporting the `C++ Core Guidelines
<https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md>`_:
- ...
* `cppcoreguidelines-pro-bounds-array-to-pointer-decay <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-array-to-pointer-decay.html>`_
* `cppcoreguidelines-pro-bounds-constant-array-index <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-constant-array-index.html>`_
* `cppcoreguidelines-pro-bounds-pointer-arithmetic <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.html>`_
* `cppcoreguidelines-pro-type-const-cast <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cppcoreguidelines-pro-type-const-cast.html>`_
* `cppcoreguidelines-pro-type-cstyle-cast <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cppcoreguidelines-pro-type-cstyle-cast.html>`_
* `cppcoreguidelines-pro-type-reinterpret-cast <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.html>`_
* `cppcoreguidelines-pro-type-static-cast-downcast <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cppcoreguidelines-pro-type-static-cast-downcast.html>`_
* `cppcoreguidelines-pro-type-union-access <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cppcoreguidelines-pro-type-union-access.html>`_
* `cppcoreguidelines-pro-type-vararg <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/cppcoreguidelines-pro-type-vararg.html>`_
* The functionality of the clang-modernize tool has been moved to the new
``modernize`` module in clang-tidy along with a few new checks:
* `modernize-loop-convert <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/modernize-loop-convert.html>`_
* `modernize-make-unique <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/modernize-make-unique.html>`_
* `modernize-pass-by-value <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/modernize-pass-by-value.html>`_
* `modernize-redundant-void-arg <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/modernize-redundant-void-arg.html>`_
* `modernize-replace-auto-ptr <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/modernize-replace-auto-ptr.html>`_
* `modernize-shrink-to-fit <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/modernize-shrink-to-fit.html>`_ (renamed from readability-shrink-to-fit)
* `modernize-use-auto <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/modernize-use-auto.html>`_
* `modernize-use-default <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/modernize-use-default.html>`_
* `modernize-use-nullptr <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/modernize-use-nullptr.html>`_
* `modernize-use-override <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/modernize-use-override.html>`_ (renamed from misc-use-override)
* New checks flagging various readability-related issues:
* `readability-identifier-naming <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/readability-identifier-naming.html>`_
* `readability-implicit-bool-cast <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/readability-implicit-bool-cast.html>`_
* `readability-inconsistent-declaration-parameter-name <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/readability-inconsistent-declaration-parameter-name.html>`_
* `readability-uniqueptr-delete-release <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/readability-uniqueptr-delete-release.html>`_
* New ``performance`` module for checks targeting potential performance issues:
* performance-unnecessary-copy-initialization
* A few new checks have been added to the ``misc`` module:
* `misc-definitions-in-headers <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/misc-definitions-in-headers.html>`_
* misc-move-const-arg
* `misc-move-constructor-init <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/misc-move-constructor-init.html>`_
* `misc-new-delete-overloads <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/misc-new-delete-overloads.html>`_
* `misc-non-copyable-objects <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/misc-non-copyable-objects.html>`_
* `misc-sizeof-container <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/misc-sizeof-container.html>`_
* `misc-string-integer-assignment <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/misc-string-integer-assignment.html>`_
* `misc-throw-by-value-catch-by-reference <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/misc-throw-by-value-catch-by-reference.html>`_
* `misc-unused-alias-decls <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/misc-unused-alias-decls.html>`_
* `misc-unused-parameters <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/misc-unused-parameters.html>`_
* `misc-virtual-near-miss <http://llvm.org/releases/3.8.0/tools/clang/tools/extra/docs/clang-tidy/checks/misc-virtual-near-miss.html>`_
Significant Known Problems
==========================
Additional Information
======================

View File

@ -5845,6 +5845,12 @@ public:
SparcTargetInfo(const llvm::Triple &Triple)
: TargetInfo(Triple), SoftFloat(false) {}
int getEHDataRegisterNumber(unsigned RegNo) const override {
if (RegNo == 0) return 24;
if (RegNo == 1) return 25;
return -1;
}
bool handleTargetFeatures(std::vector<std::string> &Features,
DiagnosticsEngine &Diags) override {
// The backend doesn't actually handle soft float yet, but in case someone

View File

@ -967,12 +967,9 @@ void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
Address ArgValue = Address::invalid();
Address ArgPtr = CGF.EmitVAArg(VE, ArgValue);
// If EmitVAArg fails, emit an error.
if (!ArgPtr.isValid()) {
// If EmitVAArg fails, we fall back to the LLVM instruction.
llvm::Value *Val = Builder.CreateVAArg(ArgValue.getPointer(),
CGF.ConvertType(VE->getType()));
if (!Dest.isIgnored())
Builder.CreateStore(Val, Dest.getAddress());
CGF.ErrorUnsupported(VE, "aggregate va_arg expression");
return;
}

View File

@ -3366,9 +3366,11 @@ Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
llvm::Type *ArgTy = ConvertType(VE->getType());
// If EmitVAArg fails, we fall back to the LLVM instruction.
if (!ArgPtr.isValid())
return Builder.CreateVAArg(ArgValue.getPointer(), ArgTy);
// If EmitVAArg fails, emit an error.
if (!ArgPtr.isValid()) {
CGF.ErrorUnsupported(VE, "va_arg expression");
return llvm::UndefValue::get(ArgTy);
}
// FIXME Volatility.
llvm::Value *Val = Builder.CreateLoad(ArgPtr);

View File

@ -523,6 +523,54 @@ static bool canExpandIndirectArgument(QualType Ty, ASTContext &Context) {
}
namespace {
Address EmitVAArgInstr(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
const ABIArgInfo &AI) {
// This default implementation defers to the llvm backend's va_arg
// instruction. It can handle only passing arguments directly
// (typically only handled in the backend for primitive types), or
// aggregates passed indirectly by pointer (NOTE: if the "byval"
// flag has ABI impact in the callee, this implementation cannot
// work.)
// Only a few cases are covered here at the moment -- those needed
// by the default abi.
llvm::Value *Val;
if (AI.isIndirect()) {
assert(!AI.getPaddingType() &&
"Unepxected PaddingType seen in arginfo in generic VAArg emitter!");
assert(
!AI.getIndirectRealign() &&
"Unepxected IndirectRealign seen in arginfo in generic VAArg emitter!");
auto TyInfo = CGF.getContext().getTypeInfoInChars(Ty);
CharUnits TyAlignForABI = TyInfo.second;
llvm::Type *BaseTy =
llvm::PointerType::getUnqual(CGF.ConvertTypeForMem(Ty));
llvm::Value *Addr =
CGF.Builder.CreateVAArg(VAListAddr.getPointer(), BaseTy);
return Address(Addr, TyAlignForABI);
} else {
assert((AI.isDirect() || AI.isExtend()) &&
"Unexpected ArgInfo Kind in generic VAArg emitter!");
assert(!AI.getInReg() &&
"Unepxected InReg seen in arginfo in generic VAArg emitter!");
assert(!AI.getPaddingType() &&
"Unepxected PaddingType seen in arginfo in generic VAArg emitter!");
assert(!AI.getDirectOffset() &&
"Unepxected DirectOffset seen in arginfo in generic VAArg emitter!");
assert(!AI.getCoerceToType() &&
"Unepxected CoerceToType seen in arginfo in generic VAArg emitter!");
Address Temp = CGF.CreateMemTemp(Ty, "varet");
Val = CGF.Builder.CreateVAArg(VAListAddr.getPointer(), CGF.ConvertType(Ty));
CGF.Builder.CreateStore(Val, Temp);
return Temp;
}
}
/// DefaultABIInfo - The default implementation for ABI specific
/// details. This implementation provides information which results in
/// self-consistent and sensible LLVM IR generation, but does not
@ -542,7 +590,9 @@ public:
}
Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType Ty) const override;
QualType Ty) const override {
return EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty));
}
};
class DefaultTargetCodeGenInfo : public TargetCodeGenInfo {
@ -551,11 +601,6 @@ public:
: TargetCodeGenInfo(new DefaultABIInfo(CGT)) {}
};
Address DefaultABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType Ty) const {
return Address::invalid();
}
ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const {
Ty = useFirstFieldIfTransparentUnion(Ty);
@ -607,7 +652,8 @@ private:
ABIArgInfo classifyArgumentType(QualType Ty) const;
// DefaultABIInfo's classifyReturnType and classifyArgumentType are
// non-virtual, but computeInfo is virtual, so we overload that.
// non-virtual, but computeInfo and EmitVAArg is virtual, so we
// overload them.
void computeInfo(CGFunctionInfo &FI) const override {
if (!getCXXABI().classifyReturnType(FI))
FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
@ -700,7 +746,13 @@ void PNaClABIInfo::computeInfo(CGFunctionInfo &FI) const {
Address PNaClABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType Ty) const {
return Address::invalid();
// The PNaCL ABI is a bit odd, in that varargs don't use normal
// function classification. Structs get passed directly for varargs
// functions, through a rewriting transform in
// pnacl-llvm/lib/Transforms/NaCl/ExpandVarArgs.cpp, which allows
// this target to actually support a va_arg instructions with an
// aggregate type, unlike other targets.
return EmitVAArgInstr(CGF, VAListAddr, Ty, ABIArgInfo::getDirect());
}
/// \brief Classify argument of given type \p Ty.
@ -3473,13 +3525,15 @@ public:
}
// TODO: this implementation is now likely redundant with
// DefaultABIInfo::EmitVAArg.
Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
QualType Ty) const {
const unsigned OverflowLimit = 8;
if (const ComplexType *CTy = Ty->getAs<ComplexType>()) {
// TODO: Implement this. For now ignore.
(void)CTy;
return Address::invalid();
return Address::invalid(); // FIXME?
}
// struct __va_list_tag {
@ -3663,7 +3717,7 @@ PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
namespace {
/// PPC64_SVR4_ABIInfo - The 64-bit PowerPC ELF (SVR4) ABI information.
class PPC64_SVR4_ABIInfo : public DefaultABIInfo {
class PPC64_SVR4_ABIInfo : public ABIInfo {
public:
enum ABIKind {
ELFv1 = 0,
@ -3705,7 +3759,7 @@ private:
public:
PPC64_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, ABIKind Kind, bool HasQPX)
: DefaultABIInfo(CGT), Kind(Kind), HasQPX(HasQPX) {}
: ABIInfo(CGT), Kind(Kind), HasQPX(HasQPX) {}
bool isPromotableTypeForABI(QualType Ty) const;
CharUnits getParamTypeAlignment(QualType Ty) const;
@ -4699,7 +4753,7 @@ Address AArch64ABIInfo::EmitDarwinVAArg(Address VAListAddr, QualType Ty,
// illegal vector types. Lower VAArg here for these cases and use
// the LLVM va_arg instruction for everything else.
if (!isAggregateTypeForABI(Ty) && !isIllegalVectorType(Ty))
return Address::invalid();
return EmitVAArgInstr(CGF, VAListAddr, Ty, ABIArgInfo::getDirect());
CharUnits SlotSize = CharUnits::fromQuantity(8);
@ -6924,6 +6978,8 @@ public:
} // End anonymous namespace.
// TODO: this implementation is likely now redundant with the default
// EmitVAArg.
Address XCoreABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType Ty) const {
CGBuilderTy &Builder = CGF.Builder;

View File

@ -8181,6 +8181,7 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_shared)) {
CmdArgs.push_back("-Bshareable");
} else {
Args.AddAllArgs(CmdArgs, options::OPT_pie);
CmdArgs.push_back("-dynamic-linker");
CmdArgs.push_back("/libexec/ld.elf_so");
}
@ -8282,15 +8283,15 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (!Args.hasArg(options::OPT_shared)) {
CmdArgs.push_back(
Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
CmdArgs.push_back(
Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
CmdArgs.push_back(
Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
} else {
CmdArgs.push_back(
Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
}
CmdArgs.push_back(
Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) {
CmdArgs.push_back(
Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
} else {
CmdArgs.push_back(
Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
}
}
@ -8356,12 +8357,12 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
if (!Args.hasArg(options::OPT_shared))
CmdArgs.push_back(
Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
else
if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
CmdArgs.push_back(
Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
else
CmdArgs.push_back(
Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
}

View File

@ -0,0 +1,10 @@
// REQUIRES: sparc-registered-target
// RUN: %clang_cc1 -triple sparc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple sparc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
void test_eh_return_data_regno(void)
{
volatile int res;
res = __builtin_eh_return_data_regno(0); // CHECK: store volatile i32 24
res = __builtin_eh_return_data_regno(1); // CHECK: store volatile i32 25
}

View File

@ -6,7 +6,9 @@ int get_int(va_list *args) {
}
// CHECK: define i32 @get_int
// CHECK: [[RESULT:%[a-z_0-9]+]] = va_arg {{.*}}, i32{{$}}
// CHECK: ret i32 [[RESULT]]
// CHECK: store i32 [[RESULT]], i32* [[LOC:%[a-z_0-9]+]]
// CHECK: [[RESULT2:%[a-z_0-9]+]] = load i32, i32* [[LOC]]
// CHECK: ret i32 [[RESULT2]]
struct Foo {
int x;
@ -19,7 +21,9 @@ void get_struct(va_list *args) {
}
// CHECK: define void @get_struct
// CHECK: [[RESULT:%[a-z_0-9]+]] = va_arg {{.*}}, %struct.Foo{{$}}
// CHECK: store %struct.Foo [[RESULT]], %struct.Foo* @dest
// CHECK: store %struct.Foo [[RESULT]], %struct.Foo* [[LOC:%[a-z_0-9]+]]
// CHECK: [[LOC2:%[a-z_0-9]+]] = bitcast {{.*}} [[LOC]] to i8*
// CHECK: call void @llvm.memcpy{{.*}}@dest{{.*}}, i8* [[LOC2]]
void skip_struct(va_list *args) {
va_arg(*args, struct Foo);

View File

@ -0,0 +1,35 @@
// RUN: %clang_cc1 -triple sparc -emit-llvm -o - %s | FileCheck %s
#include <stdarg.h>
// CHECK-LABEL: define i32 @get_int
// CHECK: [[RESULT:%[a-z_0-9]+]] = va_arg {{.*}}, i32{{$}}
// CHECK: store i32 [[RESULT]], i32* [[LOC:%[a-z_0-9]+]]
// CHECK: [[RESULT2:%[a-z_0-9]+]] = load i32, i32* [[LOC]]
// CHECK: ret i32 [[RESULT2]]
int get_int(va_list *args) {
return va_arg(*args, int);
}
struct Foo {
int x;
};
struct Foo dest;
// CHECK-LABEL: define void @get_struct
// CHECK: [[RESULT:%[a-z_0-9]+]] = va_arg {{.*}}, %struct.Foo*{{$}}
// CHECK: [[RESULT2:%[a-z_0-9]+]] = bitcast {{.*}} [[RESULT]] to i8*
// CHECK: call void @llvm.memcpy{{.*}}@dest{{.*}}, i8* [[RESULT2]]
void get_struct(va_list *args) {
dest = va_arg(*args, struct Foo);
}
enum E { Foo_one = 1 };
enum E enum_dest;
// CHECK-LABEL: define void @get_enum
// CHECK: va_arg i8** {{.*}}, i32
void get_enum(va_list *args) {
enum_dest = va_arg(*args, enum E);
}

View File

@ -1,3 +1,13 @@
// RUN: %clang -no-canonical-prefixes -target x86_64--netbsd \
// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
// RUN: | FileCheck -check-prefix=STATIC %s
// RUN: %clang -no-canonical-prefixes -target x86_64--netbsd \
// RUN: -pie --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
// RUN: | FileCheck -check-prefix=PIE %s
// RUN: %clang -no-canonical-prefixes -target x86_64--netbsd \
// RUN: -shared --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
// RUN: | FileCheck -check-prefix=SHARED %s
// RUN: %clang -no-canonical-prefixes -target x86_64--netbsd \
// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
// RUN: | FileCheck -check-prefix=X86_64 %s
@ -105,6 +115,32 @@
// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
// RUN: | FileCheck -check-prefix=S-POWERPC64 %s
// STATIC: ld{{.*}}"
// STATIC-NOT: "-pie"
// STATIC-NOT: "-Bshareable"
// STATIC: "-dynamic-linker" "/libexec/ld.elf_so"
// STATIC-NOT: "-pie"
// STATIC-NOT: "-Bshareable"
// STATIC: "{{.*}}/usr/lib{{/|\\\\}}crt0.o"
// STATIC: "{{.*}}/usr/lib{{/|\\\\}}crti.o" "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o"
// STATIC: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
// SHARED: ld{{.*}}"
// SHARED-NOT: "-pie"
// SHARED-NOT: "-dynamic-linker"
// SHARED-NOT: "{{.*}}/usr/lib{{/|\\\\}}crt0.o"
// SHARED: "{{.*}}/usr/lib{{/|\\\\}}crti.o" "{{.*}}/usr/lib{{/|\\\\}}crtbeginS.o"
// SHARED: "{{.*}}/usr/lib{{/|\\\\}}crtendS.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
// PIE: ld{{.*}}"
// PIE-NOT: "-Bshareable"
// PIE "-pie" "-dynamic-linker" "/libexec/ld.elf_so"
// PIE-NOT: "-Bshareable"
// PIE: "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
// PIE: "{{.*}}/usr/lib{{/|\\\\}}crtbeginS.o"
// PIE: "{{.*}}/usr/lib{{/|\\\\}}crtendS.o"
// PIE: "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
// X86_64: clang{{.*}}" "-cc1" "-triple" "x86_64--netbsd"
// X86_64: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
// X86_64: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"