svn commit: r311820 - in vendor/clang/dist: docs include/clang/AST include/clang/Basic include/clang/Driver include/clang/Frontend include/clang/Index include/clang/Sema include/clang/StaticAnalyze...
Dimitry Andric
dim at FreeBSD.org
Mon Jan 9 21:23:25 UTC 2017
Author: dim
Date: Mon Jan 9 21:23:21 2017
New Revision: 311820
URL: https://svnweb.freebsd.org/changeset/base/311820
Log:
Vendor import of clang trunk r291476:
https://llvm.org/svn/llvm-project/cfe/trunk@291476
Added:
vendor/clang/dist/lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp (contents, props changed)
vendor/clang/dist/test/Analysis/iterator-past-end.cpp (contents, props changed)
vendor/clang/dist/test/CodeGenCXX/dllexport-ctor-closure.cpp (contents, props changed)
vendor/clang/dist/test/Modules/Inputs/pch-with-module-name/
vendor/clang/dist/test/Modules/Inputs/pch-with-module-name/A.h (contents, props changed)
vendor/clang/dist/test/Modules/Inputs/pch-with-module-name/C.h (contents, props changed)
vendor/clang/dist/test/Modules/Inputs/pch-with-module-name/C.m
vendor/clang/dist/test/Modules/Inputs/pch-with-module-name/D.h (contents, props changed)
vendor/clang/dist/test/Modules/Inputs/pch-with-module-name/module.modulemap
vendor/clang/dist/test/Modules/Inputs/pch-with-module-name/test.h (contents, props changed)
vendor/clang/dist/test/Modules/pch-with-module-name.m
vendor/clang/dist/test/Sema/diagnose_if.c (contents, props changed)
vendor/clang/dist/test/SemaCXX/diagnose_if.cpp (contents, props changed)
vendor/clang/dist/test/SemaCXX/libstdcxx_gets_hack.cpp (contents, props changed)
Modified:
vendor/clang/dist/docs/ReleaseNotes.rst
vendor/clang/dist/include/clang/AST/Expr.h
vendor/clang/dist/include/clang/Basic/Attr.td
vendor/clang/dist/include/clang/Basic/AttrDocs.td
vendor/clang/dist/include/clang/Basic/DiagnosticCommonKinds.td
vendor/clang/dist/include/clang/Basic/DiagnosticGroups.td
vendor/clang/dist/include/clang/Basic/DiagnosticSemaKinds.td
vendor/clang/dist/include/clang/Basic/LangOptions.def
vendor/clang/dist/include/clang/Driver/CC1Options.td
vendor/clang/dist/include/clang/Frontend/CodeGenOptions.def
vendor/clang/dist/include/clang/Frontend/FrontendActions.h
vendor/clang/dist/include/clang/Index/IndexSymbol.h
vendor/clang/dist/include/clang/Sema/Initialization.h
vendor/clang/dist/include/clang/Sema/Overload.h
vendor/clang/dist/include/clang/Sema/Sema.h
vendor/clang/dist/include/clang/StaticAnalyzer/Checkers/Checkers.td
vendor/clang/dist/lib/AST/ExprConstant.cpp
vendor/clang/dist/lib/AST/MicrosoftMangle.cpp
vendor/clang/dist/lib/CodeGen/BackendUtil.cpp
vendor/clang/dist/lib/CodeGen/CGCleanup.h
vendor/clang/dist/lib/CodeGen/CGException.cpp
vendor/clang/dist/lib/CodeGen/CodeGenFunction.cpp
vendor/clang/dist/lib/Driver/ToolChains.cpp
vendor/clang/dist/lib/Driver/Tools.cpp
vendor/clang/dist/lib/Format/TokenAnnotator.cpp
vendor/clang/dist/lib/Format/UnwrappedLineParser.cpp
vendor/clang/dist/lib/Frontend/CompilerInvocation.cpp
vendor/clang/dist/lib/Frontend/FrontendActions.cpp
vendor/clang/dist/lib/Index/IndexSymbol.cpp
vendor/clang/dist/lib/Lex/PPDirectives.cpp
vendor/clang/dist/lib/Parse/ParseDecl.cpp
vendor/clang/dist/lib/Parse/ParseInit.cpp
vendor/clang/dist/lib/Sema/SemaChecking.cpp
vendor/clang/dist/lib/Sema/SemaDeclAttr.cpp
vendor/clang/dist/lib/Sema/SemaDeclCXX.cpp
vendor/clang/dist/lib/Sema/SemaExpr.cpp
vendor/clang/dist/lib/Sema/SemaExprMember.cpp
vendor/clang/dist/lib/Sema/SemaInit.cpp
vendor/clang/dist/lib/Sema/SemaLambda.cpp
vendor/clang/dist/lib/Sema/SemaLookup.cpp
vendor/clang/dist/lib/Sema/SemaOverload.cpp
vendor/clang/dist/lib/Sema/SemaTemplate.cpp
vendor/clang/dist/lib/Sema/SemaTemplateDeduction.cpp
vendor/clang/dist/lib/Sema/SemaTemplateInstantiate.cpp
vendor/clang/dist/lib/Sema/SemaTemplateInstantiateDecl.cpp
vendor/clang/dist/lib/Serialization/ASTWriter.cpp
vendor/clang/dist/lib/StaticAnalyzer/Checkers/CMakeLists.txt
vendor/clang/dist/lib/StaticAnalyzer/Core/ExprEngine.cpp
vendor/clang/dist/test/Analysis/Inputs/system-header-simulator-cxx.h
vendor/clang/dist/test/Analysis/diagnostics/explicit-suppression.cpp
vendor/clang/dist/test/Analysis/inlining/stl.cpp
vendor/clang/dist/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp
vendor/clang/dist/test/CXX/drs/dr13xx.cpp
vendor/clang/dist/test/CXX/drs/dr19xx.cpp
vendor/clang/dist/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
vendor/clang/dist/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp
vendor/clang/dist/test/CXX/temp/temp.param/p5.cpp
vendor/clang/dist/test/CodeGen/lifetime2.c
vendor/clang/dist/test/CodeGen/thinlto_backend.ll
vendor/clang/dist/test/CodeGenCXX/arm.cpp
vendor/clang/dist/test/CodeGenCXX/debug-info-class.cpp
vendor/clang/dist/test/CodeGenCXX/dllexport.cpp
vendor/clang/dist/test/CodeGenCXX/eh-aggregate-copy-destroy.cpp
vendor/clang/dist/test/CodeGenCXX/exceptions.cpp
vendor/clang/dist/test/CodeGenCXX/goto.cpp
vendor/clang/dist/test/Driver/B-opt.c
vendor/clang/dist/test/Driver/coverage-ld.c
vendor/clang/dist/test/Driver/cross-linux.c
vendor/clang/dist/test/Driver/fuchsia.c
vendor/clang/dist/test/Driver/fuchsia.cpp
vendor/clang/dist/test/Driver/fuse-ld.c
vendor/clang/dist/test/Driver/instrprof-ld.c
vendor/clang/dist/test/Driver/mips-mti-linux.c
vendor/clang/dist/test/Driver/netbsd.c
vendor/clang/dist/test/Driver/netbsd.cpp
vendor/clang/dist/test/Driver/nostdlib.c
vendor/clang/dist/test/Driver/prefixed-tools.c
vendor/clang/dist/test/Driver/sanitizer-ld.c
vendor/clang/dist/test/Driver/windows-cross.c
vendor/clang/dist/test/Index/Core/index-source.cpp
vendor/clang/dist/test/Misc/diag-template-diffing.cpp
vendor/clang/dist/test/OpenMP/atomic_codegen.cpp
vendor/clang/dist/test/OpenMP/threadprivate_codegen.cpp
vendor/clang/dist/test/SemaCXX/PR10177.cpp
vendor/clang/dist/test/SemaCXX/attr-mode-tmpl.cpp
vendor/clang/dist/test/SemaCXX/attr-noreturn.cpp
vendor/clang/dist/test/SemaCXX/constant-expression-cxx11.cpp
vendor/clang/dist/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
vendor/clang/dist/test/SemaCXX/enable_if.cpp
vendor/clang/dist/test/SemaCXX/implicit-exception-spec.cpp
vendor/clang/dist/test/SemaCXX/member-init.cpp
vendor/clang/dist/test/SemaCXX/overload-call.cpp
vendor/clang/dist/test/SemaCXX/overload-member-call.cpp
vendor/clang/dist/test/SemaCXX/undefined-internal.cpp
vendor/clang/dist/test/SemaTemplate/alias-templates.cpp
vendor/clang/dist/test/SemaTemplate/constexpr-instantiate.cpp
vendor/clang/dist/test/SemaTemplate/deduction.cpp
vendor/clang/dist/test/SemaTemplate/default-arguments-cxx0x.cpp
vendor/clang/dist/test/SemaTemplate/instantiate-init.cpp
vendor/clang/dist/test/SemaTemplate/temp_arg_nontype.cpp
vendor/clang/dist/tools/c-index-test/core_main.cpp
vendor/clang/dist/tools/driver/CMakeLists.txt
vendor/clang/dist/unittests/Format/FormatTest.cpp
vendor/clang/dist/unittests/Format/FormatTestJS.cpp
vendor/clang/dist/www/cxx_dr_status.html
Modified: vendor/clang/dist/docs/ReleaseNotes.rst
==============================================================================
--- vendor/clang/dist/docs/ReleaseNotes.rst Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/docs/ReleaseNotes.rst Mon Jan 9 21:23:21 2017 (r311820)
@@ -47,6 +47,10 @@ sections with improvements to Clang's su
Major New Features
------------------
+- The ``diagnose_if`` attribute has been added to clang. This attribute allows
+ clang to emit a warning or error if a function call meets one or more
+ user-specified conditions.
+
- ...
Improvements to Clang's diagnostics
Modified: vendor/clang/dist/include/clang/AST/Expr.h
==============================================================================
--- vendor/clang/dist/include/clang/AST/Expr.h Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/include/clang/AST/Expr.h Mon Jan 9 21:23:21 2017 (r311820)
@@ -651,7 +651,8 @@ public:
/// constant.
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
const FunctionDecl *Callee,
- ArrayRef<const Expr*> Args) const;
+ ArrayRef<const Expr*> Args,
+ const Expr *This = nullptr) const;
/// \brief If the current Expr is a pointer, this will try to statically
/// determine the number of bytes available where the pointer is pointing.
Modified: vendor/clang/dist/include/clang/Basic/Attr.td
==============================================================================
--- vendor/clang/dist/include/clang/Basic/Attr.td Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/include/clang/Basic/Attr.td Mon Jan 9 21:23:21 2017 (r311820)
@@ -140,12 +140,15 @@ class Argument<string name, bit optional
bit Fake = fake;
}
-class BoolArgument<string name, bit opt = 0> : Argument<name, opt>;
+class BoolArgument<string name, bit opt = 0, bit fake = 0> : Argument<name, opt,
+ fake>;
class IdentifierArgument<string name, bit opt = 0> : Argument<name, opt>;
class IntArgument<string name, bit opt = 0> : Argument<name, opt>;
class StringArgument<string name, bit opt = 0> : Argument<name, opt>;
class ExprArgument<string name, bit opt = 0> : Argument<name, opt>;
-class FunctionArgument<string name, bit opt = 0> : Argument<name, opt>;
+class FunctionArgument<string name, bit opt = 0, bit fake = 0> : Argument<name,
+ opt,
+ fake>;
class TypeArgument<string name, bit opt = 0> : Argument<name, opt>;
class UnsignedArgument<string name, bit opt = 0> : Argument<name, opt>;
class VariadicUnsignedArgument<string name> : Argument<name, 1>;
@@ -1591,6 +1594,26 @@ def Unavailable : InheritableAttr {
let Documentation = [Undocumented];
}
+def DiagnoseIf : InheritableAttr {
+ let Spellings = [GNU<"diagnose_if">];
+ let Subjects = SubjectList<[Function]>;
+ let Args = [ExprArgument<"Cond">, StringArgument<"Message">,
+ EnumArgument<"DiagnosticType",
+ "DiagnosticType",
+ ["error", "warning"],
+ ["DT_Error", "DT_Warning"]>,
+ BoolArgument<"ArgDependent", 0, /*fake*/ 1>,
+ FunctionArgument<"Parent", 0, /*fake*/ 1>];
+ let DuplicatesAllowedWhileMerging = 1;
+ let LateParsed = 1;
+ let AdditionalMembers = [{
+ bool isError() const { return diagnosticType == DT_Error; }
+ bool isWarning() const { return diagnosticType == DT_Warning; }
+ }];
+ let TemplateDependent = 1;
+ let Documentation = [DiagnoseIfDocs];
+}
+
def ArcWeakrefUnavailable : InheritableAttr {
let Spellings = [GNU<"objc_arc_weak_reference_unavailable">];
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
Modified: vendor/clang/dist/include/clang/Basic/AttrDocs.td
==============================================================================
--- vendor/clang/dist/include/clang/Basic/AttrDocs.td Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/include/clang/Basic/AttrDocs.td Mon Jan 9 21:23:21 2017 (r311820)
@@ -378,6 +378,65 @@ template instantiation, so the value for
}];
}
+def DiagnoseIfDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``diagnose_if`` attribute can be placed on function declarations to emit
+warnings or errors at compile-time if calls to the attributed function meet
+certain user-defined criteria. For example:
+
+.. code-block:: c
+ void abs(int a)
+ __attribute__((diagnose_if(a >= 0, "Redundant abs call", "warning")));
+ void must_abs(int a)
+ __attribute__((diagnose_if(a >= 0, "Redundant abs call", "error")));
+
+ int val = abs(1); // warning: Redundant abs call
+ int val2 = must_abs(1); // error: Redundant abs call
+ int val3 = abs(val);
+ int val4 = must_abs(val); // Because run-time checks are not emitted for
+ // diagnose_if attributes, this executes without
+ // issue.
+
+
+``diagnose_if`` is closely related to ``enable_if``, with a few key differences:
+
+* Overload resolution is not aware of ``diagnose_if`` attributes: they're
+ considered only after we select the best candidate from a given candidate set.
+* Function declarations that differ only in their ``diagnose_if`` attributes are
+ considered to be redeclarations of the same function (not overloads).
+* If the condition provided to ``diagnose_if`` cannot be evaluated, no
+ diagnostic will be emitted.
+
+Otherwise, ``diagnose_if`` is essentially the logical negation of ``enable_if``.
+
+As a result of bullet number two, ``diagnose_if`` attributes will stack on the
+same function. For example:
+
+.. code-block:: c
+
+ int foo() __attribute__((diagnose_if(1, "diag1", "warning")));
+ int foo() __attribute__((diagnose_if(1, "diag2", "warning")));
+
+ int bar = foo(); // warning: diag1
+ // warning: diag2
+ int (*fooptr)(void) = foo; // warning: diag1
+ // warning: diag2
+
+ constexpr int supportsAPILevel(int N) { return N < 5; }
+ int baz(int a)
+ __attribute__((diagnose_if(!supportsAPILevel(10),
+ "Upgrade to API level 10 to use baz", "error")));
+ int baz(int a)
+ __attribute__((diagnose_if(!a, "0 is not recommended.", "warning")));
+
+ int (*bazptr)(int) = baz; // error: Upgrade to API level 10 to use baz
+ int v = baz(0); // error: Upgrade to API level 10 to use baz
+
+Query for this feature with ``__has_attribute(diagnose_if)``.
+ }];
+}
+
def PassObjectSizeDocs : Documentation {
let Category = DocCatVariable; // Technically it's a parameter doc, but eh.
let Content = [{
Modified: vendor/clang/dist/include/clang/Basic/DiagnosticCommonKinds.td
==============================================================================
--- vendor/clang/dist/include/clang/Basic/DiagnosticCommonKinds.td Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/include/clang/Basic/DiagnosticCommonKinds.td Mon Jan 9 21:23:21 2017 (r311820)
@@ -161,6 +161,8 @@ def ext_old_implicitly_unsigned_long_cxx
InGroup<CXX11Compat>;
def ext_clang_enable_if : Extension<"'enable_if' is a clang extension">,
InGroup<GccCompat>;
+def ext_clang_diagnose_if : Extension<"'diagnose_if' is a clang extension">,
+ InGroup<GccCompat>;
// SEH
def err_seh_expected_handler : Error<
Modified: vendor/clang/dist/include/clang/Basic/DiagnosticGroups.td
==============================================================================
--- vendor/clang/dist/include/clang/Basic/DiagnosticGroups.td Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/include/clang/Basic/DiagnosticGroups.td Mon Jan 9 21:23:21 2017 (r311820)
@@ -495,6 +495,7 @@ def UnusedPropertyIvar : DiagGroup<"unu
def UnusedGetterReturnValue : DiagGroup<"unused-getter-return-value">;
def UsedButMarkedUnused : DiagGroup<"used-but-marked-unused">;
def UserDefinedLiterals : DiagGroup<"user-defined-literals">;
+def UserDefinedWarnings : DiagGroup<"user-defined-warnings">;
def Reorder : DiagGroup<"reorder">;
def UndeclaredSelector : DiagGroup<"undeclared-selector">;
def ImplicitAtomic : DiagGroup<"implicit-atomic-properties">;
@@ -683,7 +684,8 @@ def Most : DiagGroup<"most", [
OverloadedVirtual,
PrivateExtern,
SelTypeCast,
- ExternCCompat
+ ExternCCompat,
+ UserDefinedWarnings
]>;
// Thread Safety warnings
Modified: vendor/clang/dist/include/clang/Basic/DiagnosticSemaKinds.td
==============================================================================
--- vendor/clang/dist/include/clang/Basic/DiagnosticSemaKinds.td Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/include/clang/Basic/DiagnosticSemaKinds.td Mon Jan 9 21:23:21 2017 (r311820)
@@ -2141,8 +2141,11 @@ def err_constexpr_local_var_no_init : Er
def ext_constexpr_function_never_constant_expr : ExtWarn<
"constexpr %select{function|constructor}0 never produces a "
"constant expression">, InGroup<DiagGroup<"invalid-constexpr">>, DefaultError;
-def err_enable_if_never_constant_expr : Error<
- "'enable_if' attribute expression never produces a constant expression">;
+def err_attr_cond_never_constant_expr : Error<
+ "%0 attribute expression never produces a constant expression">;
+def err_diagnose_if_invalid_diagnostic_type : Error<
+ "invalid diagnostic type for 'diagnose_if'; use \"error\" or \"warning\" "
+ "instead">;
def err_constexpr_body_no_return : Error<
"no return statement in constexpr function">;
def err_constexpr_return_missing_expr : Error<
@@ -3333,6 +3336,9 @@ def note_ovl_candidate : Note<"candidate
def note_ovl_candidate_inherited_constructor : Note<
"constructor from base class %0 inherited here">;
+def note_ovl_candidate_inherited_constructor_slice : Note<
+ "constructor inherited from base class cannot be used to initialize from "
+ "an argument of the derived class type">;
def note_ovl_candidate_illegal_constructor : Note<
"candidate %select{constructor|template}0 ignored: "
"instantiation %select{takes|would take}0 its own class type by value">;
@@ -3366,7 +3372,9 @@ def note_ovl_candidate_disabled_by_enabl
def note_ovl_candidate_has_pass_object_size_params: Note<
"candidate address cannot be taken because parameter %0 has "
"pass_object_size attribute">;
-def note_ovl_candidate_disabled_by_enable_if_attr : Note<
+def err_diagnose_if_succeeded : Error<"%0">;
+def warn_diagnose_if_succeeded : Warning<"%0">, InGroup<UserDefinedWarnings>;
+def note_ovl_candidate_disabled_by_function_cond_attr : Note<
"candidate disabled: %0">;
def note_ovl_candidate_disabled_by_extension : Note<
"candidate disabled due to OpenCL extension">;
@@ -4395,6 +4403,7 @@ def note_not_found_by_two_phase_lookup :
def err_undeclared_use : Error<"use of undeclared %0">;
def warn_deprecated : Warning<"%0 is deprecated">,
InGroup<DeprecatedDeclarations>;
+def note_from_diagnose_if : Note<"from 'diagnose_if' attribute on %0:">;
def warn_property_method_deprecated :
Warning<"property access is using %0 method which is deprecated">,
InGroup<DeprecatedDeclarations>;
Modified: vendor/clang/dist/include/clang/Basic/LangOptions.def
==============================================================================
--- vendor/clang/dist/include/clang/Basic/LangOptions.def Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/include/clang/Basic/LangOptions.def Mon Jan 9 21:23:21 2017 (r311820)
@@ -146,6 +146,7 @@ LANGOPT(Modules , 1, 0, "modul
COMPATIBLE_LANGOPT(ModulesTS , 1, 0, "C++ Modules TS")
BENIGN_ENUM_LANGOPT(CompilingModule, CompilingModuleKind, 2, CMK_None,
"compiling a module interface")
+BENIGN_LANGOPT(CompilingPCH, 1, 0, "building a pch")
COMPATIBLE_LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses")
BENIGN_LANGOPT(ModulesSearchAll , 1, 1, "searching even non-imported modules to find unresolved references")
COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "requiring declaration of module uses and all headers to be in modules")
Modified: vendor/clang/dist/include/clang/Driver/CC1Options.td
==============================================================================
--- vendor/clang/dist/include/clang/Driver/CC1Options.td Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/include/clang/Driver/CC1Options.td Mon Jan 9 21:23:21 2017 (r311820)
@@ -167,6 +167,9 @@ def disable_llvm_passes : Flag<["-"], "d
"frontend by not running any LLVM passes at all">;
def disable_llvm_optzns : Flag<["-"], "disable-llvm-optzns">,
Alias<disable_llvm_passes>;
+def disable_lifetimemarkers : Flag<["-"], "disable-lifetime-markers">,
+ HelpText<"Disable lifetime-markers emission even when optimizations are "
+ "enabled">;
def disable_red_zone : Flag<["-"], "disable-red-zone">,
HelpText<"Do not emit code that uses the red zone.">;
def dwarf_column_info : Flag<["-"], "dwarf-column-info">,
Modified: vendor/clang/dist/include/clang/Frontend/CodeGenOptions.def
==============================================================================
--- vendor/clang/dist/include/clang/Frontend/CodeGenOptions.def Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/include/clang/Frontend/CodeGenOptions.def Mon Jan 9 21:23:21 2017 (r311820)
@@ -52,6 +52,7 @@ CODEGENOPT(DisableGCov , 1, 0) ///
CODEGENOPT(DisableLLVMPasses , 1, 0) ///< Don't run any LLVM IR passes to get
///< the pristine IR generated by the
///< frontend.
+CODEGENOPT(DisableLifetimeMarkers, 1, 0) ///< Don't emit any lifetime markers
CODEGENOPT(ExperimentalNewPassManager, 1, 0) ///< Enables the new, experimental
///< pass manager.
CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled.
Modified: vendor/clang/dist/include/clang/Frontend/FrontendActions.h
==============================================================================
--- vendor/clang/dist/include/clang/Frontend/FrontendActions.h Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/include/clang/Frontend/FrontendActions.h Mon Jan 9 21:23:21 2017 (r311820)
@@ -88,6 +88,8 @@ public:
static std::unique_ptr<raw_pwrite_stream>
ComputeASTConsumerArguments(CompilerInstance &CI, StringRef InFile,
std::string &Sysroot, std::string &OutputFile);
+
+ bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
};
class GenerateModuleAction : public ASTFrontendAction {
Modified: vendor/clang/dist/include/clang/Index/IndexSymbol.h
==============================================================================
--- vendor/clang/dist/include/clang/Index/IndexSymbol.h Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/include/clang/Index/IndexSymbol.h Mon Jan 9 21:23:21 2017 (r311820)
@@ -59,6 +59,13 @@ enum class SymbolLanguage {
CXX,
};
+/// Language specific sub-kinds.
+enum class SymbolSubKind {
+ None,
+ CXXCopyConstructor,
+ CXXMoveConstructor,
+};
+
/// Set of properties that provide additional info about a symbol.
enum class SymbolProperty : uint8_t {
Generic = 1 << 0,
@@ -107,6 +114,7 @@ struct SymbolRelation {
struct SymbolInfo {
SymbolKind Kind;
+ SymbolSubKind SubKind;
SymbolPropertySet Properties;
SymbolLanguage Lang;
};
@@ -121,6 +129,7 @@ void printSymbolRoles(SymbolRoleSet Role
bool printSymbolName(const Decl *D, const LangOptions &LO, raw_ostream &OS);
StringRef getSymbolKindString(SymbolKind K);
+StringRef getSymbolSubKindString(SymbolSubKind K);
StringRef getSymbolLanguageString(SymbolLanguage K);
void applyForEachSymbolProperty(SymbolPropertySet Props,
Modified: vendor/clang/dist/include/clang/Sema/Initialization.h
==============================================================================
--- vendor/clang/dist/include/clang/Sema/Initialization.h Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/include/clang/Sema/Initialization.h Mon Jan 9 21:23:21 2017 (r311820)
@@ -215,14 +215,14 @@ public:
/// \brief Create the initialization entity for a parameter.
static InitializedEntity InitializeParameter(ASTContext &Context,
- ParmVarDecl *Parm) {
+ const ParmVarDecl *Parm) {
return InitializeParameter(Context, Parm, Parm->getType());
}
/// \brief Create the initialization entity for a parameter, but use
/// another type.
static InitializedEntity InitializeParameter(ASTContext &Context,
- ParmVarDecl *Parm,
+ const ParmVarDecl *Parm,
QualType Type) {
bool Consumed = (Context.getLangOpts().ObjCAutoRefCount &&
Parm->hasAttr<NSConsumedAttr>());
Modified: vendor/clang/dist/include/clang/Sema/Overload.h
==============================================================================
--- vendor/clang/dist/include/clang/Sema/Overload.h Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/include/clang/Sema/Overload.h Mon Jan 9 21:23:21 2017 (r311820)
@@ -531,6 +531,13 @@ namespace clang {
Ambiguous.construct();
}
+ void setAsIdentityConversion(QualType T) {
+ setStandard();
+ Standard.setAsIdentityConversion();
+ Standard.setFromType(T);
+ Standard.setAllToTypes(T);
+ }
+
/// \brief Whether the target is really a std::initializer_list, and the
/// sequence only represents the worst element conversion.
bool isStdInitializerListElement() const {
@@ -601,8 +608,17 @@ namespace clang {
/// This candidate was not viable because its OpenCL extension is disabled.
ovl_fail_ext_disabled,
+
+ /// This inherited constructor is not viable because it would slice the
+ /// argument.
+ ovl_fail_inhctor_slice,
};
+ /// A list of implicit conversion sequences for the arguments of an
+ /// OverloadCandidate.
+ typedef llvm::MutableArrayRef<ImplicitConversionSequence>
+ ConversionSequenceList;
+
/// OverloadCandidate - A single candidate in an overload set (C++ 13.3).
struct OverloadCandidate {
/// Function - The actual function that this candidate
@@ -627,18 +643,13 @@ namespace clang {
/// is a surrogate, but only if IsSurrogate is true.
CXXConversionDecl *Surrogate;
- /// Conversions - The conversion sequences used to convert the
- /// function arguments to the function parameters, the pointer points to a
- /// fixed size array with NumConversions elements. The memory is owned by
- /// the OverloadCandidateSet.
- ImplicitConversionSequence *Conversions;
+ /// The conversion sequences used to convert the function arguments
+ /// to the function parameters.
+ ConversionSequenceList Conversions;
/// The FixIt hints which can be used to fix the Bad candidate.
ConversionFixItGenerator Fix;
- /// NumConversions - The number of elements in the Conversions array.
- unsigned NumConversions;
-
/// Viable - True to indicate that this overload candidate is viable.
bool Viable;
@@ -664,6 +675,26 @@ namespace clang {
/// to be used while performing partial ordering of function templates.
unsigned ExplicitCallArguments;
+ /// The number of diagnose_if attributes that this overload triggered.
+ /// If any of the triggered attributes are errors, this won't count
+ /// diagnose_if warnings.
+ unsigned NumTriggeredDiagnoseIfs = 0;
+
+ /// Basically a TinyPtrVector<DiagnoseIfAttr *> that doesn't own the vector:
+ /// If NumTriggeredDiagnoseIfs is 0 or 1, this is a DiagnoseIfAttr *,
+ /// otherwise it's a pointer to an array of `NumTriggeredDiagnoseIfs`
+ /// DiagnoseIfAttr *s.
+ llvm::PointerUnion<DiagnoseIfAttr *, DiagnoseIfAttr **> DiagnoseIfInfo;
+
+ /// Gets an ArrayRef for the data at DiagnoseIfInfo. Note that this may give
+ /// you a pointer into DiagnoseIfInfo.
+ ArrayRef<DiagnoseIfAttr *> getDiagnoseIfInfo() const {
+ auto *Ptr = NumTriggeredDiagnoseIfs <= 1
+ ? DiagnoseIfInfo.getAddrOfPtr1()
+ : DiagnoseIfInfo.get<DiagnoseIfAttr **>();
+ return {Ptr, NumTriggeredDiagnoseIfs};
+ }
+
union {
DeductionFailureInfo DeductionFailure;
@@ -677,9 +708,9 @@ namespace clang {
/// hasAmbiguousConversion - Returns whether this overload
/// candidate requires an ambiguous conversion or not.
bool hasAmbiguousConversion() const {
- for (unsigned i = 0, e = NumConversions; i != e; ++i) {
- if (!Conversions[i].isInitialized()) return false;
- if (Conversions[i].isAmbiguous()) return true;
+ for (auto &C : Conversions) {
+ if (!C.isInitialized()) return false;
+ if (C.isAmbiguous()) return true;
}
return false;
}
@@ -728,17 +759,42 @@ namespace clang {
SmallVector<OverloadCandidate, 16> Candidates;
llvm::SmallPtrSet<Decl *, 16> Functions;
- // Allocator for OverloadCandidate::Conversions. We store the first few
- // elements inline to avoid allocation for small sets.
- llvm::BumpPtrAllocator ConversionSequenceAllocator;
+ // Allocator for ConversionSequenceLists and DiagnoseIfAttr* arrays.
+ // We store the first few of each of these inline to avoid allocation for
+ // small sets.
+ llvm::BumpPtrAllocator SlabAllocator;
SourceLocation Loc;
CandidateSetKind Kind;
- unsigned NumInlineSequences;
- llvm::AlignedCharArray<alignof(ImplicitConversionSequence),
- 16 * sizeof(ImplicitConversionSequence)>
- InlineSpace;
+ constexpr static unsigned NumInlineBytes =
+ 24 * sizeof(ImplicitConversionSequence);
+ unsigned NumInlineBytesUsed;
+ llvm::AlignedCharArray<alignof(void *), NumInlineBytes> InlineSpace;
+
+ /// If we have space, allocates from inline storage. Otherwise, allocates
+ /// from the slab allocator.
+ /// FIXME: It would probably be nice to have a SmallBumpPtrAllocator
+ /// instead.
+ template <typename T>
+ T *slabAllocate(unsigned N) {
+ // It's simpler if this doesn't need to consider alignment.
+ static_assert(alignof(T) == alignof(void *),
+ "Only works for pointer-aligned types.");
+ static_assert(std::is_trivial<T>::value ||
+ std::is_same<ImplicitConversionSequence, T>::value,
+ "Add destruction logic to OverloadCandidateSet::clear().");
+
+ unsigned NBytes = sizeof(T) * N;
+ if (NBytes > NumInlineBytes - NumInlineBytesUsed)
+ return SlabAllocator.Allocate<T>(N);
+ char *FreeSpaceStart = InlineSpace.buffer + NumInlineBytesUsed;
+ assert(uintptr_t(FreeSpaceStart) % alignof(void *) == 0 &&
+ "Misaligned storage!");
+
+ NumInlineBytesUsed += NBytes;
+ return reinterpret_cast<T *>(FreeSpaceStart);
+ }
OverloadCandidateSet(const OverloadCandidateSet &) = delete;
void operator=(const OverloadCandidateSet &) = delete;
@@ -747,12 +803,17 @@ namespace clang {
public:
OverloadCandidateSet(SourceLocation Loc, CandidateSetKind CSK)
- : Loc(Loc), Kind(CSK), NumInlineSequences(0) {}
+ : Loc(Loc), Kind(CSK), NumInlineBytesUsed(0) {}
~OverloadCandidateSet() { destroyCandidates(); }
SourceLocation getLocation() const { return Loc; }
CandidateSetKind getKind() const { return Kind; }
+ /// Make a DiagnoseIfAttr* array in a block of memory that will live for
+ /// as long as this OverloadCandidateSet. Returns a pointer to the start
+ /// of that array.
+ DiagnoseIfAttr **addDiagnoseIfComplaints(ArrayRef<DiagnoseIfAttr *> CA);
+
/// \brief Determine when this overload candidate will be new to the
/// overload set.
bool isNewCandidate(Decl *F) {
@@ -769,30 +830,32 @@ namespace clang {
size_t size() const { return Candidates.size(); }
bool empty() const { return Candidates.empty(); }
+ /// \brief Allocate storage for conversion sequences for NumConversions
+ /// conversions.
+ ConversionSequenceList
+ allocateConversionSequences(unsigned NumConversions) {
+ ImplicitConversionSequence *Conversions =
+ slabAllocate<ImplicitConversionSequence>(NumConversions);
+
+ // Construct the new objects.
+ for (unsigned I = 0; I != NumConversions; ++I)
+ new (&Conversions[I]) ImplicitConversionSequence();
+
+ return ConversionSequenceList(Conversions, NumConversions);
+ }
+
/// \brief Add a new candidate with NumConversions conversion sequence slots
/// to the overload set.
- OverloadCandidate &addCandidate(unsigned NumConversions = 0) {
+ OverloadCandidate &addCandidate(unsigned NumConversions = 0,
+ ConversionSequenceList Conversions = None) {
+ assert((Conversions.empty() || Conversions.size() == NumConversions) &&
+ "preallocated conversion sequence has wrong length");
+
Candidates.push_back(OverloadCandidate());
OverloadCandidate &C = Candidates.back();
-
- // Assign space from the inline array if there are enough free slots
- // available.
- if (NumConversions + NumInlineSequences <= 16) {
- ImplicitConversionSequence *I =
- (ImplicitConversionSequence *)InlineSpace.buffer;
- C.Conversions = &I[NumInlineSequences];
- NumInlineSequences += NumConversions;
- } else {
- // Otherwise get memory from the allocator.
- C.Conversions = ConversionSequenceAllocator
- .Allocate<ImplicitConversionSequence>(NumConversions);
- }
-
- // Construct the new objects.
- for (unsigned i = 0; i != NumConversions; ++i)
- new (&C.Conversions[i]) ImplicitConversionSequence();
-
- C.NumConversions = NumConversions;
+ C.Conversions = Conversions.empty()
+ ? allocateConversionSequences(NumConversions)
+ : Conversions;
return C;
}
Modified: vendor/clang/dist/include/clang/Sema/Sema.h
==============================================================================
--- vendor/clang/dist/include/clang/Sema/Sema.h Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/include/clang/Sema/Sema.h Mon Jan 9 21:23:21 2017 (r311820)
@@ -27,6 +27,7 @@
#include "clang/AST/NSAPI.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/TypeLoc.h"
+#include "clang/AST/TypeOrdering.h"
#include "clang/Basic/ExpressionTraits.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
@@ -119,6 +120,7 @@ namespace clang {
class FunctionProtoType;
class FunctionTemplateDecl;
class ImplicitConversionSequence;
+ typedef MutableArrayRef<ImplicitConversionSequence> ConversionSequenceList;
class InitListExpr;
class InitializationKind;
class InitializationSequence;
@@ -806,6 +808,12 @@ public:
/// run time.
Unevaluated,
+ /// \brief The current expression occurs within a braced-init-list within
+ /// an unevaluated operand. This is mostly like a regular unevaluated
+ /// context, except that we still instantiate constexpr functions that are
+ /// referenced here so that we can perform narrowing checks correctly.
+ UnevaluatedList,
+
/// \brief The current expression occurs within a discarded statement.
/// This behaves largely similarly to an unevaluated operand in preventing
/// definitions from being required, but not in other ways.
@@ -898,7 +906,8 @@ public:
MangleNumberingContext &getMangleNumberingContext(ASTContext &Ctx);
bool isUnevaluated() const {
- return Context == Unevaluated || Context == UnevaluatedAbstract;
+ return Context == Unevaluated || Context == UnevaluatedAbstract ||
+ Context == UnevaluatedList;
}
};
@@ -2510,10 +2519,11 @@ public:
void AddOverloadCandidate(FunctionDecl *Function,
DeclAccessPair FoundDecl,
ArrayRef<Expr *> Args,
- OverloadCandidateSet& CandidateSet,
+ OverloadCandidateSet &CandidateSet,
bool SuppressUserConversions = false,
bool PartialOverloading = false,
- bool AllowExplicit = false);
+ bool AllowExplicit = false,
+ ConversionSequenceList EarlyConversions = None);
void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
ArrayRef<Expr *> Args,
OverloadCandidateSet &CandidateSet,
@@ -2523,23 +2533,25 @@ public:
void AddMethodCandidate(DeclAccessPair FoundDecl,
QualType ObjectType,
Expr::Classification ObjectClassification,
- ArrayRef<Expr *> Args,
+ Expr *ThisArg, ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversion = false);
void AddMethodCandidate(CXXMethodDecl *Method,
DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext, QualType ObjectType,
Expr::Classification ObjectClassification,
- ArrayRef<Expr *> Args,
+ Expr *ThisArg, ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false,
- bool PartialOverloading = false);
+ bool PartialOverloading = false,
+ ConversionSequenceList EarlyConversions = None);
void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext,
TemplateArgumentListInfo *ExplicitTemplateArgs,
QualType ObjectType,
Expr::Classification ObjectClassification,
+ Expr *ThisArg,
ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false,
@@ -2551,6 +2563,16 @@ public:
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false,
bool PartialOverloading = false);
+ bool CheckNonDependentConversions(FunctionTemplateDecl *FunctionTemplate,
+ ArrayRef<QualType> ParamTypes,
+ ArrayRef<Expr *> Args,
+ OverloadCandidateSet &CandidateSet,
+ ConversionSequenceList &Conversions,
+ bool SuppressUserConversions,
+ CXXRecordDecl *ActingContext = nullptr,
+ QualType ObjectType = QualType(),
+ Expr::Classification
+ ObjectClassification = {});
void AddConversionCandidate(CXXConversionDecl *Conversion,
DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext,
@@ -2603,6 +2625,38 @@ public:
EnableIfAttr *CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
bool MissingImplicitThis = false);
+ /// Check the diagnose_if attributes on the given function. Returns the
+ /// first succesful fatal attribute, or null if calling Function(Args) isn't
+ /// an error.
+ ///
+ /// This only considers ArgDependent DiagnoseIfAttrs.
+ ///
+ /// This will populate Nonfatal with all non-error DiagnoseIfAttrs that
+ /// succeed. If this function returns non-null, the contents of Nonfatal are
+ /// unspecified.
+ DiagnoseIfAttr *
+ checkArgDependentDiagnoseIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
+ SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal,
+ bool MissingImplicitThis = false,
+ Expr *ThisArg = nullptr);
+
+ /// Check the diagnose_if expressions on the given function. Returns the
+ /// first succesful fatal attribute, or null if using Function isn't
+ /// an error.
+ ///
+ /// This ignores all ArgDependent DiagnoseIfAttrs.
+ ///
+ /// This will populate Nonfatal with all non-error DiagnoseIfAttrs that
+ /// succeed. If this function returns non-null, the contents of Nonfatal are
+ /// unspecified.
+ DiagnoseIfAttr *
+ checkArgIndependentDiagnoseIf(FunctionDecl *Function,
+ SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal);
+
+ /// Emits the diagnostic contained in the given DiagnoseIfAttr at Loc. Also
+ /// emits a note about the location of said attribute.
+ void emitDiagnoseIfDiagnostic(SourceLocation Loc, const DiagnoseIfAttr *DIA);
+
/// Returns whether the given function's address can be taken or not,
/// optionally emitting a diagnostic if the address can't be taken.
///
@@ -3801,6 +3855,9 @@ public:
/// variable will have in the given scope.
QualType getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc);
+ /// Mark all of the declarations referenced within a particular AST node as
+ /// referenced. Used when template instantiation instantiates a non-dependent
+ /// type -- entities referenced by the type are now referenced.
void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T);
void MarkDeclarationsReferencedInExpr(Expr *E,
bool SkipLocalVariables = false);
@@ -6580,6 +6637,8 @@ public:
/// \brief The explicitly-specified template arguments were not valid
/// template arguments for the given template.
TDK_InvalidExplicitArguments,
+ /// \brief Checking non-dependent argument conversions failed.
+ TDK_NonDependentConversionFailure,
/// \brief Deduction failed; that's all we know.
TDK_MiscellaneousDeductionFailure,
/// \brief CUDA Target attributes do not match.
@@ -6618,22 +6677,21 @@ public:
QualType OriginalArgType;
};
- TemplateDeductionResult
- FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- unsigned NumExplicitlySpecified,
- FunctionDecl *&Specialization,
- sema::TemplateDeductionInfo &Info,
- SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = nullptr,
- bool PartialOverloading = false);
+ TemplateDeductionResult FinishTemplateArgumentDeduction(
+ FunctionTemplateDecl *FunctionTemplate,
+ SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+ unsigned NumExplicitlySpecified, FunctionDecl *&Specialization,
+ sema::TemplateDeductionInfo &Info,
+ SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = nullptr,
+ bool PartialOverloading = false,
+ llvm::function_ref<bool()> CheckNonDependent = []{ return false; });
- TemplateDeductionResult
- DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
- TemplateArgumentListInfo *ExplicitTemplateArgs,
- ArrayRef<Expr *> Args,
- FunctionDecl *&Specialization,
- sema::TemplateDeductionInfo &Info,
- bool PartialOverloading = false);
+ TemplateDeductionResult DeduceTemplateArguments(
+ FunctionTemplateDecl *FunctionTemplate,
+ TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
+ FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info,
+ bool PartialOverloading,
+ llvm::function_ref<bool(ArrayRef<QualType>)> CheckNonDependent);
TemplateDeductionResult
DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
@@ -6877,6 +6935,10 @@ public:
/// Specializations whose definitions are currently being instantiated.
llvm::DenseSet<std::pair<Decl *, unsigned>> InstantiatingSpecializations;
+ /// Non-dependent types used in templates that have already been instantiated
+ /// by some template instantiation.
+ llvm::DenseSet<QualType> InstantiatedNonDependentTypes;
+
/// \brief Extra modules inspected when performing a lookup during a template
/// instantiation. Computed lazily.
SmallVector<Module*, 16> ActiveTemplateInstantiationLookupModules;
@@ -10186,6 +10248,22 @@ public:
IsDecltype);
}
+ enum InitListTag { InitList };
+ EnterExpressionEvaluationContext(Sema &Actions, InitListTag,
+ bool ShouldEnter = true)
+ : Actions(Actions), Entered(false) {
+ // In C++11 onwards, narrowing checks are performed on the contents of
+ // braced-init-lists, even when they occur within unevaluated operands.
+ // Therefore we still need to instantiate constexpr functions used in such
+ // a context.
+ if (ShouldEnter && Actions.isUnevaluatedContext() &&
+ Actions.getLangOpts().CPlusPlus11) {
+ Actions.PushExpressionEvaluationContext(Sema::UnevaluatedList, nullptr,
+ false);
+ Entered = true;
+ }
+ }
+
~EnterExpressionEvaluationContext() {
if (Entered)
Actions.PopExpressionEvaluationContext();
Modified: vendor/clang/dist/include/clang/StaticAnalyzer/Checkers/Checkers.td
==============================================================================
--- vendor/clang/dist/include/clang/StaticAnalyzer/Checkers/Checkers.td Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/include/clang/StaticAnalyzer/Checkers/Checkers.td Mon Jan 9 21:23:21 2017 (r311820)
@@ -278,6 +278,14 @@ def VirtualCallChecker : Checker<"Virtua
} // end: "optin.cplusplus"
+let ParentPackage = CplusplusAlpha in {
+
+def IteratorPastEndChecker : Checker<"IteratorPastEnd">,
+ HelpText<"Check iterators used past end">,
+ DescFile<"IteratorPastEndChecker.cpp">;
+
+} // end: "alpha.cplusplus"
+
//===----------------------------------------------------------------------===//
// Valist checkers.
Modified: vendor/clang/dist/lib/AST/ExprConstant.cpp
==============================================================================
--- vendor/clang/dist/lib/AST/ExprConstant.cpp Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/lib/AST/ExprConstant.cpp Mon Jan 9 21:23:21 2017 (r311820)
@@ -4543,6 +4543,12 @@ public:
Call.getLValueBase().dyn_cast<const ValueDecl*>());
if (!FD)
return Error(Callee);
+ // Don't call function pointers which have been cast to some other type.
+ // Per DR (no number yet), the caller and callee can differ in noexcept.
+ if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
+ CalleeType->getPointeeType(), FD->getType())) {
+ return Error(E);
+ }
// Overloaded operator calls to member functions are represented as normal
// calls with '*this' as the first argument.
@@ -4558,14 +4564,42 @@ public:
return false;
This = &ThisVal;
Args = Args.slice(1);
+ } else if (MD && MD->isLambdaStaticInvoker()) {
+ // Map the static invoker for the lambda back to the call operator.
+ // Conveniently, we don't have to slice out the 'this' argument (as is
+ // being done for the non-static case), since a static member function
+ // doesn't have an implicit argument passed in.
+ const CXXRecordDecl *ClosureClass = MD->getParent();
+ assert(
+ ClosureClass->captures_begin() == ClosureClass->captures_end() &&
+ "Number of captures must be zero for conversion to function-ptr");
+
+ const CXXMethodDecl *LambdaCallOp =
+ ClosureClass->getLambdaCallOperator();
+
+ // Set 'FD', the function that will be called below, to the call
+ // operator. If the closure object represents a generic lambda, find
+ // the corresponding specialization of the call operator.
+
+ if (ClosureClass->isGenericLambda()) {
+ assert(MD->isFunctionTemplateSpecialization() &&
+ "A generic lambda's static-invoker function must be a "
+ "template specialization");
+ const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs();
+ FunctionTemplateDecl *CallOpTemplate =
+ LambdaCallOp->getDescribedFunctionTemplate();
+ void *InsertPos = nullptr;
+ FunctionDecl *CorrespondingCallOpSpecialization =
+ CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos);
+ assert(CorrespondingCallOpSpecialization &&
+ "We must always have a function call operator specialization "
+ "that corresponds to our static invoker specialization");
+ FD = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
+ } else
+ FD = LambdaCallOp;
}
- // Don't call function pointers which have been cast to some other type.
- // Per DR (no number yet), the caller and callee can differ in noexcept.
- if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
- CalleeType->getPointeeType(), FD->getType())) {
- return Error(E);
- }
+
} else
return Error(E);
@@ -5834,6 +5868,7 @@ namespace {
bool VisitCXXConstructExpr(const CXXConstructExpr *E) {
return VisitCXXConstructExpr(E, E->getType());
}
+ bool VisitLambdaExpr(const LambdaExpr *E);
bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E);
bool VisitCXXConstructExpr(const CXXConstructExpr *E, QualType T);
bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E);
@@ -6168,6 +6203,21 @@ bool RecordExprEvaluator::VisitCXXStdIni
return true;
}
+bool RecordExprEvaluator::VisitLambdaExpr(const LambdaExpr *E) {
+ const CXXRecordDecl *ClosureClass = E->getLambdaClass();
+ if (ClosureClass->isInvalidDecl()) return false;
+
+ if (Info.checkingPotentialConstantExpression()) return true;
+ if (E->capture_size()) {
+ Info.FFDiag(E, diag::note_unimplemented_constexpr_lambda_feature_ast)
+ << "can not evaluate lambda expressions with captures";
+ return false;
+ }
+ // FIXME: Implement captures.
+ Result = APValue(APValue::UninitStruct(), /*NumBases*/0, /*NumFields*/0);
+ return true;
+}
+
static bool EvaluateRecord(const Expr *E, const LValue &This,
APValue &Result, EvalInfo &Info) {
assert(E->isRValue() && E->getType()->isRecordType() &&
@@ -6217,6 +6267,9 @@ public:
bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr *E) {
return VisitConstructExpr(E);
}
+ bool VisitLambdaExpr(const LambdaExpr *E) {
+ return VisitConstructExpr(E);
+ }
};
} // end anonymous namespace
@@ -10357,10 +10410,25 @@ bool Expr::isCXX11ConstantExpr(const AST
bool Expr::EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
const FunctionDecl *Callee,
- ArrayRef<const Expr*> Args) const {
+ ArrayRef<const Expr*> Args,
+ const Expr *This) const {
Expr::EvalStatus Status;
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
+ LValue ThisVal;
+ const LValue *ThisPtr = nullptr;
+ if (This) {
+#ifndef NDEBUG
+ auto *MD = dyn_cast<CXXMethodDecl>(Callee);
+ assert(MD && "Don't provide `this` for non-methods.");
+ assert(!MD->isStatic() && "Don't provide `this` for static methods.");
+#endif
+ if (EvaluateObjectArgument(Info, This, ThisVal))
+ ThisPtr = &ThisVal;
+ if (Info.EvalStatus.HasSideEffects)
+ return false;
+ }
+
ArgVector ArgValues(Args.size());
for (ArrayRef<const Expr*>::iterator I = Args.begin(), E = Args.end();
I != E; ++I) {
@@ -10373,7 +10441,7 @@ bool Expr::EvaluateWithSubstitution(APVa
}
// Build fake call to Callee.
- CallStackFrame Frame(Info, Callee->getLocation(), Callee, /*This*/nullptr,
+ CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
ArgValues.data());
return Evaluate(Value, Info, this) && !Info.EvalStatus.HasSideEffects;
}
Modified: vendor/clang/dist/lib/AST/MicrosoftMangle.cpp
==============================================================================
--- vendor/clang/dist/lib/AST/MicrosoftMangle.cpp Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/lib/AST/MicrosoftMangle.cpp Mon Jan 9 21:23:21 2017 (r311820)
@@ -109,13 +109,13 @@ static const DeclContext *getEffectivePa
static const FunctionDecl *getStructor(const NamedDecl *ND) {
if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
- return FTD->getTemplatedDecl();
+ return FTD->getTemplatedDecl()->getCanonicalDecl();
const auto *FD = cast<FunctionDecl>(ND);
if (const auto *FTD = FD->getPrimaryTemplate())
- return FTD->getTemplatedDecl();
+ return FTD->getTemplatedDecl()->getCanonicalDecl();
- return FD;
+ return FD->getCanonicalDecl();
}
/// MicrosoftMangleContextImpl - Overrides the default MangleContext for the
@@ -312,6 +312,10 @@ public:
void mangleNestedName(const NamedDecl *ND);
private:
+ bool isStructorDecl(const NamedDecl *ND) const {
+ return ND == Structor || getStructor(ND) == Structor;
+ }
+
void mangleUnqualifiedName(const NamedDecl *ND) {
mangleUnqualifiedName(ND, ND->getDeclName());
}
@@ -898,7 +902,7 @@ void MicrosoftCXXNameMangler::mangleUnqu
llvm_unreachable("Can't mangle Objective-C selector names here!");
case DeclarationName::CXXConstructorName:
- if (Structor == getStructor(ND)) {
+ if (isStructorDecl(ND)) {
if (StructorType == Ctor_CopyingClosure) {
Out << "?_O";
return;
@@ -912,7 +916,7 @@ void MicrosoftCXXNameMangler::mangleUnqu
return;
case DeclarationName::CXXDestructorName:
- if (ND == Structor)
+ if (isStructorDecl(ND))
// If the named decl is the C++ destructor we're mangling,
// use the type we were given.
mangleCXXDtorType(static_cast<CXXDtorType>(StructorType));
@@ -1862,7 +1866,7 @@ void MicrosoftCXXNameMangler::mangleFunc
IsStructor = true;
IsCtorClosure = (StructorType == Ctor_CopyingClosure ||
StructorType == Ctor_DefaultClosure) &&
- getStructor(MD) == Structor;
+ isStructorDecl(MD);
if (IsCtorClosure)
CC = getASTContext().getDefaultCallingConvention(
/*IsVariadic=*/false, /*IsCXXMethod=*/true);
@@ -1883,7 +1887,7 @@ void MicrosoftCXXNameMangler::mangleFunc
// <return-type> ::= <type>
// ::= @ # structors (they have no declared return type)
if (IsStructor) {
- if (isa<CXXDestructorDecl>(D) && D == Structor &&
+ if (isa<CXXDestructorDecl>(D) && isStructorDecl(D) &&
StructorType == Dtor_Deleting) {
// The scalar deleting destructor takes an extra int argument.
// However, the FunctionType generated has 0 arguments.
Modified: vendor/clang/dist/lib/CodeGen/BackendUtil.cpp
==============================================================================
--- vendor/clang/dist/lib/CodeGen/BackendUtil.cpp Mon Jan 9 21:23:15 2017 (r311819)
+++ vendor/clang/dist/lib/CodeGen/BackendUtil.cpp Mon Jan 9 21:23:21 2017 (r311820)
@@ -312,7 +312,8 @@ void EmitAssemblyHelper::CreatePasses(le
// At O0 and O1 we only run the always inliner which is more efficient. At
// higher optimization levels we run the normal inliner.
if (CodeGenOpts.OptimizationLevel <= 1) {
- bool InsertLifetimeIntrinsics = CodeGenOpts.OptimizationLevel != 0;
+ bool InsertLifetimeIntrinsics = (CodeGenOpts.OptimizationLevel != 0 &&
+ !CodeGenOpts.DisableLifetimeMarkers);
PMBuilder.Inliner = createAlwaysInlinerLegacyPass(InsertLifetimeIntrinsics);
} else {
PMBuilder.Inliner = createFunctionInliningPass(
@@ -519,11 +520,22 @@ void EmitAssemblyHelper::CreateTargetMac
.Case("dynamic-no-pic", llvm::Reloc::DynamicNoPIC);
assert(RM.hasValue() && "invalid PIC model!");
- CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
+ CodeGenOpt::Level OptLevel;
switch (CodeGenOpts.OptimizationLevel) {
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list