diff options
author | Philip Withnall <philip@tecnocode.co.uk> | 2019-12-16 21:32:47 +0000 |
---|---|---|
committer | Philip Withnall <philip@tecnocode.co.uk> | 2019-12-16 21:32:47 +0000 |
commit | 0a1c3fa2c6f1498d17ad24fe976b17e3c81f3a90 (patch) | |
tree | 9eeadf250fdb5f0b6ffd5d8e4a0e7010160ad7e1 | |
parent | 515d0c9ace06c4be4243fc5ae06e25456d9452c9 (diff) | |
parent | 5fb0dafcafbb34a503b301f807fb5c8a6efe326a (diff) |
Merge branch '5-upgrade-clang' into 'master'
Resolve "Support Clang 5.x"
Closes #5
See merge request tartan/tartan!2
35 files changed, 499 insertions, 574 deletions
diff --git a/Makefile.am b/Makefile.am index ab23235..764ca8c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -68,7 +68,6 @@ clang_plugin_libtartan_la_LDFLAGS = \ $(WARN_LDFLAGS) \ -avoid-version \ -module \ - -no-undefined \ $(NULL) # Clang and scan-build wrapper scripts @@ -17,7 +17,7 @@ Dependencies • glib-2.0 ≥ 2.38.0 • gio-2.0 ≥ 2.38.0 • gobject-introspection-1.0 ≥ 1.38.0 - • llvm ≥ 3.5 + • llvm ≥ 7.0 Licensing ========= diff --git a/clang-plugin/assertion-extracter.cpp b/clang-plugin/assertion-extracter.cpp index 80fcf59..61ec110 100644 --- a/clang-plugin/assertion-extracter.cpp +++ b/clang-plugin/assertion-extracter.cpp @@ -70,7 +70,8 @@ _negation_expr (Expr* e, const ASTContext& context) return new (context) UnaryOperator (e, UnaryOperatorKind::UO_LNot, context.getLogicalOperationType (), - VK_RValue, OK_Ordinary, SourceLocation ()); + VK_RValue, OK_Ordinary, SourceLocation (), + /* can_overflow = */ false); } /* Combine expressions A and B to give (A && B). */ @@ -81,7 +82,7 @@ _conjunction_expr (Expr* lhs, Expr* rhs, const ASTContext& context) BinaryOperator (lhs, rhs, BinaryOperatorKind::BO_LAnd, context.getLogicalOperationType (), VK_RValue, OK_Ordinary, SourceLocation (), - false); + FPOptions ()); } /* Combine expressions A and B to give (A || B). */ @@ -92,7 +93,7 @@ _disjunction_expr (Expr* lhs, Expr* rhs, const ASTContext& context) BinaryOperator (lhs, rhs, BinaryOperatorKind::BO_LOr, context.getLogicalOperationType (), VK_RValue, OK_Ordinary, SourceLocation (), - false); + FPOptions ()); } /* Does the given statement look like: @@ -532,7 +533,7 @@ _simplify_boolean_expr (Expr* expr, const ASTContext& context) BinaryOperator (lhs, rhs, opcode, context.getLogicalOperationType (), VK_RValue, OK_Ordinary, SourceLocation (), - false); + FPOptions ()); } /* ! (S1 op S2) ↦ ! (simplify(S1) op simplify(S2)) */ diff --git a/clang-plugin/debug.cpp b/clang-plugin/debug.cpp index de14658..05d2fe5 100644 --- a/clang-plugin/debug.cpp +++ b/clang-plugin/debug.cpp @@ -37,11 +37,7 @@ void Debug::emit_bug_report (std::unique_ptr<BugReport> report, CheckerContext &context) { - #ifndef HAVE_LLVM_3_7 - context.emitReport (report.get ()); - #else context.emitReport (std::move (report)); - #endif } /* Build and emit a warning or error report about the user’s code. */ diff --git a/clang-plugin/gassert-attributes.cpp b/clang-plugin/gassert-attributes.cpp index 29f97ef..362a120 100644 --- a/clang-plugin/gassert-attributes.cpp +++ b/clang-plugin/gassert-attributes.cpp @@ -65,7 +65,7 @@ _handle_assertion (FunctionDecl& func, Expr& assertion_expr, return; /* TODO: Factor out the code to augment a nonnull attribute. */ - std::vector<unsigned int> non_null_args; + std::vector<ParamIdx> non_null_args; NonNullAttr* nonnull_attr = func.getAttr<NonNullAttr> (); if (nonnull_attr != NULL) { @@ -92,23 +92,16 @@ _handle_assertion (FunctionDecl& func, Expr& assertion_expr, unsigned int j = parm_decl->getFunctionScopeIndex (); DEBUG ("Got nonnull arg " << j << " (" << val_decl->getNameAsString () << ") from assertion."); - non_null_args.push_back (j); + /* ParamIdx is 1-based. */ + non_null_args.push_back (ParamIdx (j + 1, &func)); } if (non_null_args.size () > 0) { -#ifdef HAVE_LLVM_3_5 nonnull_attr = ::new (func.getASTContext ()) NonNullAttr (func.getSourceRange (), func.getASTContext (), non_null_args.data (), non_null_args.size (), 0); -#else /* if !HAVE_LLVM_3_5 */ - nonnull_attr = ::new (func.getASTContext ()) - NonNullAttr (func.getSourceRange (), - func.getASTContext (), - non_null_args.data (), - non_null_args.size ()); -#endif /* !HAVE_LLVM_3_5 */ func.addAttr (nonnull_attr); } } diff --git a/clang-plugin/gerror-checker.cpp b/clang-plugin/gerror-checker.cpp index 43c341b..df9f5c7 100644 --- a/clang-plugin/gerror-checker.cpp +++ b/clang-plugin/gerror-checker.cpp @@ -421,8 +421,8 @@ GErrorChecker::_handle_eval_g_propagate_error (CheckerContext &context, return state; } - DEBUG_DUMPABLE ("Handle post-g_propagate_error: dest_location:", - dest_location); + DEBUG_DUMPABLE ("Handle post-g_propagate_error: dest_ptr_location:", + dest_ptr_location); DEBUG_DUMPABLE ("Handle post-g_propagate_error: src_location:", src_location); @@ -505,9 +505,19 @@ GErrorChecker::checkPreCall (const CallEvent &call, /* Dispatch call-evaluation events to the different per-function handlers. * Return true iff the call was evaluated. */ bool -GErrorChecker::evalCall (const CallExpr *call, +GErrorChecker::evalCall ( +#ifdef HAVE_LLVM_9_0 + const CallEvent &call_event, +#else + const CallExpr *call, +#endif CheckerContext &context) const { +#ifdef HAVE_LLVM_9_0 + const CallExpr *call = llvm::dyn_cast<CallExpr>(call_event.getOriginExpr()); + if (!call) + return false; +#endif const FunctionDecl *func_decl = context.getCalleeDecl (call); if (func_decl == NULL || @@ -616,9 +626,11 @@ void GErrorChecker::checkDeadSymbols (SymbolReaper &symbol_reaper, CheckerContext &context) const { +#ifndef HAVE_LLVM_8_0 if (!symbol_reaper.hasDeadSymbols ()) { return; } +#endif ProgramStateRef state = context.getState (); @@ -679,7 +691,8 @@ GErrorChecker::_gerror_new (const Expr *call_expr, } /* Fill the region with the initialization value. */ - state = state->bindDefault (*allocated_sval, UndefinedVal ()); + state = state->bindDefaultInitial (*allocated_sval, UndefinedVal (), + context.getLocationContext ()); const MemRegion *allocated_region = allocated_sval->getAsRegion (); assert (allocated_region); @@ -732,7 +745,7 @@ GErrorChecker::_gerror_free (SVal error_location, ProgramStateRef state, /* Fill the MemRegion with rubbish. */ if (error_location.getAs<Loc> ()) { state = state->bindLoc (error_location.castAs<Loc> (), - UndefinedVal ()); + UndefinedVal (), context.getLocationContext ()); assert (state != NULL); } @@ -764,11 +777,7 @@ GErrorChecker::_assert_gerror_set (SVal error_location, const SourceRange &source_range) const { if (error_location.getAs<UndefinedVal> ()) { -#if HAVE_LLVM_3_8 ExplodedNode *error_node = context.generateErrorNode (state); -#else - ExplodedNode *error_node = context.generateSink (state); -#endif this->_initialise_bug_reports (); auto R = llvm::make_unique<BugReport> (*this->_use_uninitialised, @@ -793,11 +802,7 @@ GErrorChecker::_assert_gerror_set (SVal error_location, state->assume (error_location.castAs<DefinedOrUnknownSVal> ()); if (null_state && !not_null_state && !null_allowed) { /* Definitely NULL. */ -#if HAVE_LLVM_3_8 ExplodedNode *error_node = context.generateErrorNode (state); -#else - ExplodedNode *error_node = context.generateSink (state); -#endif this->_initialise_bug_reports (); auto R = llvm::make_unique<BugReport> (*this->_free_cleared, @@ -826,11 +831,7 @@ GErrorChecker::_assert_gerror_set (SVal error_location, const ErrorState *error_state = _error_map_get (state, error_sym); if (error_state != NULL && error_state->isFreed ()) { -#if HAVE_LLVM_3_8 ExplodedNode *error_node = context.generateErrorNode (state); -#else - ExplodedNode *error_node = context.generateSink (state); -#endif this->_initialise_bug_reports (); auto R = llvm::make_unique<BugReport> (*this->_double_free, @@ -842,13 +843,7 @@ GErrorChecker::_assert_gerror_set (SVal error_location, return false; } else if (error_state != NULL && !error_state->isSet ()) { -#if HAVE_LLVM_3_8 ExplodedNode *error_node = context.generateErrorNode (state); -#else - ExplodedNode *error_node = context.generateSink (state); -#endif - - this->_initialise_bug_reports (); auto R = llvm::make_unique<BugReport> (*this->_free_cleared, @@ -929,13 +924,7 @@ GErrorChecker::_assert_gerror_unset (SVal error_location, /* Branch on whether the GError* is NULL. If it isn’t NULL, there’s a * bug. */ if (error_location.getAs<UndefinedVal> () && !undef_allowed) { -#if HAVE_LLVM_3_8 ExplodedNode *error_node = context.generateErrorNode (state); -#else - ExplodedNode *error_node = context.generateSink (state); -#endif - - this->_initialise_bug_reports (); auto R = llvm::make_unique<BugReport> (*this->_use_uninitialised, @@ -970,13 +959,7 @@ GErrorChecker::_assert_gerror_unset (SVal error_location, const ErrorState *error_state = _error_map_get (state, error_sym); if (error_state != NULL && error_state->isSet ()) { -#if HAVE_LLVM_3_8 ExplodedNode *error_node = context.generateErrorNode (state); -#else - ExplodedNode *error_node = context.generateSink (state); -#endif - - this->_initialise_bug_reports (); auto R = llvm::make_unique<BugReport> (*this->_overwrite_set, @@ -989,13 +972,7 @@ GErrorChecker::_assert_gerror_unset (SVal error_location, return false; } else if (error_state != NULL && error_state->isFreed () && !undef_allowed) { -#if HAVE_LLVM_3_8 ExplodedNode *error_node = context.generateErrorNode (state); -#else - ExplodedNode *error_node = context.generateSink (state); -#endif - - this->_initialise_bug_reports (); auto R = llvm::make_unique<BugReport> (*this->_overwrite_freed, @@ -1040,7 +1017,8 @@ GErrorChecker::_set_gerror (SVal error_location, const SourceRange &source_range) const { /* Bind the error location to the new error. */ - state = state->bindLoc (error_location, new_error); + state = state->bindLoc (error_location, new_error, + context.getLocationContext ()); assert (state != NULL); /* Constrain the GError* location (lvalue) and rvalue to be non-NULL. */ @@ -1076,7 +1054,8 @@ GErrorChecker::_clear_gerror (SVal error_location, /* Bind the GError* to NULL. */ SValBuilder &sval_builder = context.getSValBuilder (); - state = state->bindLoc (error_location, sval_builder.makeNull ()); + state = state->bindLoc (error_location, sval_builder.makeNull (), + context.getLocationContext ()); assert (state != NULL); /* Constrain the GError* location (lvalue) to be NULL. */ diff --git a/clang-plugin/gerror-checker.h b/clang-plugin/gerror-checker.h index 5fdff0e..1d7ce80 100644 --- a/clang-plugin/gerror-checker.h +++ b/clang-plugin/gerror-checker.h @@ -23,6 +23,8 @@ #ifndef TARTAN_GERROR_CHECKER_H #define TARTAN_GERROR_CHECKER_H +#include "config.h" + #include <clang/AST/AST.h> #include <clang/StaticAnalyzer/Core/BugReporter/BugType.h> #include <clang/StaticAnalyzer/Core/Checker.h> @@ -159,7 +161,12 @@ private: public: void checkPreCall (const CallEvent &call, CheckerContext &context) const; - bool evalCall (const CallExpr *call, + bool evalCall ( +#ifdef HAVE_LLVM_9_0 + const CallEvent &call_event, +#else + const CallExpr *call, +#endif CheckerContext &context) const; void checkBind (SVal loc, SVal val, const Stmt *stmt, CheckerContext &context) const; diff --git a/clang-plugin/gir-attributes.cpp b/clang-plugin/gir-attributes.cpp index 8309eca..49dd9ae 100644 --- a/clang-plugin/gir-attributes.cpp +++ b/clang-plugin/gir-attributes.cpp @@ -72,12 +72,7 @@ _arg_is_nonnull (GIArgInfo arg, GITypeInfo type_info) static bool _function_return_type_is_const (FunctionDecl& func) { -#ifdef HAVE_LLVM_3_5 QualType type = func.getReturnType (); -#else /* if !HAVE_LLVM_3_5 */ - QualType type = func.getResultType (); -#endif /* !HAVE_LLVM_3_5 */ - QualType canonical_type = type.getCanonicalType (); const PointerType* pointer_type = dyn_cast<PointerType> (canonical_type); @@ -105,11 +100,7 @@ _constify_function_return_type (FunctionDecl& func) * is immutable. */ const FunctionType* f_type = func.getType ()->getAs<FunctionType> (); ASTContext& context = func.getASTContext (); -#ifdef HAVE_LLVM_3_5 const QualType old_result_type = f_type->getReturnType (); -#else /* if !HAVE_LLVM_3_5 */ - const QualType old_result_type = f_type->getResultType (); -#endif /* !HAVE_LLVM_3_5 */ const PointerType* old_result_pointer_type = dyn_cast<PointerType> (old_result_type); if (old_result_pointer_type == NULL) @@ -131,13 +122,7 @@ _constify_function_return_type (FunctionDecl& func) } else { const FunctionProtoType *f_p_type = cast<FunctionProtoType> (f_type); - ArrayRef<QualType> param_types; - -#ifdef HAVE_LLVM_3_5 - param_types = f_p_type->getParamTypes (); -#else /* !HAVE_LLVM_3_5 */ - param_types = f_p_type->getArgTypes (); -#endif /* !HAVE_LLVM_3_5 */ + ArrayRef<QualType> param_types = f_p_type->getParamTypes (); t = context.getFunctionType (new_result_type, param_types, @@ -222,7 +207,7 @@ GirAttributesConsumer::_handle_function_decl (FunctionDecl& func) break; } - std::vector<unsigned int> non_null_args; + std::vector<ParamIdx> non_null_args; unsigned int j; NonNullAttr* nonnull_attr = func.getAttr<NonNullAttr> (); @@ -245,11 +230,6 @@ GirAttributesConsumer::_handle_function_decl (FunctionDecl& func) transfer = g_arg_info_get_ownership_transfer (&arg); type_tag = g_type_info_get_tag (&type_info); - DEBUG_CODE (int array_type = - (g_type_info_get_tag (&type_info) == - GI_TYPE_TAG_ARRAY) ? - g_type_info_get_array_type (&type_info) : - -1); DEBUG ("GirAttributes: " << func_name << "(" << j << ")\n" "\tTransfer: " << transfer << "\n" @@ -265,7 +245,9 @@ GirAttributesConsumer::_handle_function_decl (FunctionDecl& func) g_type_tag_to_string ( g_type_info_get_tag (&type_info)) << "\n" "\tArray type: " << - array_type << "\n" + ((g_type_info_get_tag (&type_info) == GI_TYPE_TAG_ARRAY) ? + g_type_info_get_array_type (&type_info) : + -1) << "\n" "\tArray length: " << g_type_info_get_array_length (&type_info) << "\n" "\tArray fixed size: " << @@ -274,7 +256,8 @@ GirAttributesConsumer::_handle_function_decl (FunctionDecl& func) if (_arg_is_nonnull (arg, type_info)) { DEBUG ("Got nonnull arg " << obj_params + j << " from GIR."); - non_null_args.push_back (obj_params + j); + /* ParamIdx is 1-based. */ + non_null_args.push_back (ParamIdx (obj_params + j + 1, &func)); } if (_type_should_be_const (transfer, type_tag)) { @@ -288,19 +271,11 @@ GirAttributesConsumer::_handle_function_decl (FunctionDecl& func) if (non_null_args.size () > 0 && !_ignore_glib_internal_func (func_name)) { -#ifdef HAVE_LLVM_3_5 nonnull_attr = ::new (func.getASTContext ()) NonNullAttr (func.getSourceRange (), func.getASTContext (), non_null_args.data (), non_null_args.size (), 0); -#else /* if !HAVE_LLVM_3_5 */ - nonnull_attr = ::new (func.getASTContext ()) - NonNullAttr (func.getSourceRange (), - func.getASTContext (), - non_null_args.data (), - non_null_args.size ()); -#endif /* !HAVE_LLVM_3_5 */ func.addAttr (nonnull_attr); } @@ -316,17 +291,10 @@ GirAttributesConsumer::_handle_function_decl (FunctionDecl& func) return_type_tag = g_type_info_get_tag (&return_type_info); if (return_transfer != GI_TRANSFER_NOTHING) { -#ifdef HAVE_LLVM_3_5 WarnUnusedAttr* warn_unused_attr = ::new (func.getASTContext ()) WarnUnusedAttr (func.getSourceRange (), func.getASTContext (), 0); -#else /* if !HAVE_LLVM_3_5 */ - WarnUnusedAttr* warn_unused_attr = - ::new (func.getASTContext ()) - WarnUnusedAttr (func.getSourceRange (), - func.getASTContext ()); -#endif /* !HAVE_LLVM_3_5 */ func.addAttr (warn_unused_attr); } else if (_type_should_be_const (return_transfer, return_type_tag)) { @@ -338,33 +306,16 @@ GirAttributesConsumer::_handle_function_decl (FunctionDecl& func) * or replacement function so we can’t make use of them. */ if (g_base_info_is_deprecated (info) && !func.hasAttr<DeprecatedAttr> ()) { -#ifdef HAVE_LLVM_3_8 DeprecatedAttr* deprecated_attr = ::new (func.getASTContext ()) DeprecatedAttr (func.getSourceRange (), func.getASTContext (), 0); -#elif HAVE_LLVM_3_5 - DeprecatedAttr* deprecated_attr = - ::new (func.getASTContext ()) - DeprecatedAttr (func.getSourceRange (), - func.getASTContext (), - "Deprecated using the gtk-doc " - "attribute.", 0); -#else /* if !HAVE_LLVM_3_5 */ - DeprecatedAttr* deprecated_attr = - ::new (func.getASTContext ()) - DeprecatedAttr (func.getSourceRange (), - func.getASTContext (), - "Deprecated using the gtk-doc " - "attribute."); -#endif /* !HAVE_LLVM_3_5 */ func.addAttr (deprecated_attr); } /* Mark the function as allocating memory if it’s a * constructor. */ -#if defined(HAVE_LLVM_3_7) if (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR && !func.hasAttr<RestrictAttr> ()) { @@ -374,27 +325,6 @@ GirAttributesConsumer::_handle_function_decl (FunctionDecl& func) func.getASTContext (), 0); func.addAttr (malloc_attr); } -#elif defined(HAVE_LLVM_3_6) - if (g_function_info_get_flags (info) & - GI_FUNCTION_IS_CONSTRUCTOR && - !func.hasAttr<MallocAttr> ()) { - MallocAttr* malloc_attr = - ::new (func.getASTContext ()) - MallocAttr (func.getSourceRange (), - func.getASTContext (), 0); - func.addAttr (malloc_attr); - } -#else - if (g_function_info_get_flags (info) & - GI_FUNCTION_IS_CONSTRUCTOR && - !func.hasAttr<MallocAttr> ()) { - MallocAttr* malloc_attr = - ::new (func.getASTContext ()) - MallocAttr (func.getSourceRange (), - func.getASTContext ()); - func.addAttr (malloc_attr); - } -#endif break; } @@ -512,7 +442,12 @@ GirAttributesChecker::_handle_function_decl (FunctionDecl& func) "return value of function %0() (already has a " "const modifier).", this->_compiler, - func.getLocStart ()) +#ifdef HAVE_LLVM_8_0 + func.getBeginLoc () +#else + func.getLocStart () +#endif + ) << func.getNameAsString (); } else if (return_transfer == GI_TRANSFER_NOTHING && _type_should_be_const (return_transfer, @@ -523,7 +458,12 @@ GirAttributesChecker::_handle_function_decl (FunctionDecl& func) "function %0() (already has a (transfer none) " "annotation).", this->_compiler, - func.getLocStart ()) +#ifdef HAVE_LLVM_8_0 + func.getBeginLoc () +#else + func.getLocStart () +#endif + ) << func.getNameAsString (); } diff --git a/clang-plugin/gsignal-checker.cpp b/clang-plugin/gsignal-checker.cpp index 2f8cb50..5f7dfda 100644 --- a/clang-plugin/gsignal-checker.cpp +++ b/clang-plugin/gsignal-checker.cpp @@ -578,6 +578,8 @@ _is_gtype_subclass (GIBaseInfo *a, GIBaseInfo *b) * Note: This is used for C++ non-static member function calls (when using * MSVC++), so we cannot use C++ methods for callbacks with swapped * parameters. + * • Microsoft vectorcall: Same. + * - aarch64: vectorcall is assumed to be unsafe as it is on x86. * * References: * [1]: http://en.wikipedia.org/wiki/X86_calling_conventions @@ -616,45 +618,34 @@ calling_convention_is_safe (CallingConv conv) { switch (conv) { case CC_C: /* cdecl */ - case CC_X86_64Win64: /* x86-64 */ + case CC_Win64: /* x86-64 */ case CC_X86_64SysV: /* x86-64 */ case CC_AAPCS: /* ARM */ case CC_AAPCS_VFP: /* ARM with VFP registers */ -#ifndef HAVE_LLVM_3_7 - case CC_PnaclCall: /* Chromium PNC — equivalent to cdecl */ -#endif -#ifdef HAVE_LLVM_3_7 - case CC_X86VectorCall: -#endif -#ifdef HAVE_LLVM_3_9 case CC_Swift: /* Swift — lowered to C calling conventions */ case CC_PreserveMost: /* arguments passed identically to cdecl */ case CC_PreserveAll: /* arguments passed identically to cdecl */ -#endif -#ifdef HAVE_LLVM_4_0 case CC_X86RegCall: -#endif return true; case CC_X86StdCall: case CC_X86FastCall: case CC_X86ThisCall: case CC_X86Pascal: + case CC_X86VectorCall: +#ifdef HAVE_LLVM_8_0 + case CC_AArch64VectorCall: +#endif return false; case CC_IntelOclBicc: /* Intel OpenCL Built-Ins. I can’t find any documentation about * this, so let’s consider it unsafe. */ -#ifdef HAVE_LLVM_3_9 case CC_SpirFunction: case CC_OpenCLKernel: -#elif HAVE_LLVM_3_8 - case CC_SpirFunction: - case CC_SpirKernel: /* OpenCL SPIR calling conventions. These are ‘defined’ in §3.7 * of * https://www.khronos.org/files/opencl-spir-12-provisional.pdf, * but without enough information to classify them as safe or * unsafe. */ -#endif default: return false; } @@ -709,7 +700,13 @@ _check_signal_callback_type (const Expr *expr, "for signal ‘%0::%1’. Callback " "function declaration does not " "contain parameter types.", - compiler, expr->getLocStart ()) + compiler, +#ifdef HAVE_LLVM_8_0 + expr->getBeginLoc () +#else + expr->getLocStart () +#endif + ) << gir_manager.get_c_name_for_type (static_instance_info) << g_base_info_get_name (signal_info) << decl_range; @@ -782,13 +779,7 @@ _check_signal_callback_type (const Expr *expr, */ GICallableInfo *callable_info = signal_info; guint n_signal_args = g_callable_info_get_n_args (callable_info) + 2; - guint n_callback_args; - -#ifdef HAVE_LLVM_3_5 - n_callback_args = callback_type->getNumParams (); -#else /* if !HAVE_LLVM_3_5 */ - n_callback_args = callback_type->getNumArgs (); -#endif /* !HAVE_LLVM_3_5 */ + guint n_callback_args = callback_type->getNumParams (); GITypeInfo expected_type_info; QualType actual_type, expected_type; @@ -802,7 +793,13 @@ _check_signal_callback_type (const Expr *expr, Debug::emit_error ("Incorrect number of arguments in signal " "handler for signal ‘%0::%1’. Expected %2 " "but saw %3.", - compiler, expr->getLocStart ()) + compiler, +#ifdef HAVE_LLVM_8_0 + expr->getBeginLoc () +#else + expr->getLocStart () +#endif + ) << gir_manager.get_c_name_for_type (static_instance_info) << g_base_info_get_name (signal_info) << n_signal_args @@ -817,11 +814,7 @@ _check_signal_callback_type (const Expr *expr, const gchar *arg_name; bool type_error; -#ifdef HAVE_LLVM_3_5 actual_type = callback_type->getParamType (i); -#else /* if !HAVE_LLVM_3_5 */ - actual_type = callback_type->getArgType (i); -#endif /* !HAVE_LLVM_3_5 */ if ((i == 0 && !is_swapped) || (i == n_signal_args - 1 && is_swapped)) { @@ -866,7 +859,12 @@ _check_signal_callback_type (const Expr *expr, "signal ‘%1::%2’. Cannot " "find type with name " "‘%3’.", compiler, - expr->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + expr->getBeginLoc () +#else + expr->getLocStart () +#endif + ) << arg_name << c_type << g_base_info_get_name (signal_info) @@ -917,7 +915,12 @@ _check_signal_callback_type (const Expr *expr, "for signal ‘%1::%2’. It " "should be ‘%3’ but is " "currently ‘%4’.", compiler, - expr->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + expr->getBeginLoc () +#else + expr->getLocStart () +#endif + ) << arg_name << gir_manager.get_c_name_for_type (static_instance_info) << g_base_info_get_name (signal_info) @@ -931,7 +934,12 @@ _check_signal_callback_type (const Expr *expr, "for signal ‘%1::%2’. It " "should be ‘%3’ but is " "currently ‘%4’.", compiler, - expr->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + expr->getBeginLoc () +#else + expr->getLocStart () +#endif + ) << arg_name << gir_manager.get_c_name_for_type (static_instance_info) << g_base_info_get_name (signal_info) @@ -995,7 +1003,12 @@ _check_signal_callback_type (const Expr *expr, "signal ‘%1::%2’. Cannot " "find type with name " "‘%3’.", compiler, - expr->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + expr->getBeginLoc () +#else + expr->getLocStart () +#endif + ) << arg_name << gir_manager.get_c_name_for_type (static_instance_info) << g_base_info_get_name (signal_info) @@ -1026,7 +1039,12 @@ _check_signal_callback_type (const Expr *expr, "in swapped signal handler for " "signal ‘%1::%2’. Expected ‘%3’ but " "saw ‘%4’.", compiler, - expr->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + expr->getBeginLoc () +#else + expr->getLocStart () +#endif + ) << arg_name << gir_manager.get_c_name_for_type (static_instance_info) << g_base_info_get_name (signal_info) @@ -1043,7 +1061,12 @@ _check_signal_callback_type (const Expr *expr, "in signal handler for signal " "‘%1::%2’. Expected ‘%3’ but saw " "‘%4’.", compiler, - expr->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + expr->getBeginLoc () +#else + expr->getLocStart () +#endif + ) << arg_name << gir_manager.get_c_name_for_type (static_instance_info) << g_base_info_get_name (signal_info) @@ -1057,11 +1080,7 @@ _check_signal_callback_type (const Expr *expr, /* Return type. */ g_callable_info_load_return_type (callable_info, &expected_type_info); -#ifdef HAVE_LLVM_3_5 actual_type = callback_type->getReturnType (); -#else /* !HAVE_LLVM_3_5 */ - actual_type = callback_type->getResultType (); -#endif /* HAVE_LLVM_3_5 */ expected_type = _type_info_to_type (&expected_type_info, context, gir_manager, type_manager); if (expected_type.isNull ()) { @@ -1071,7 +1090,12 @@ _check_signal_callback_type (const Expr *expr, Debug::emit_warning ("Failed to resolve return type in signal " "handler for signal ‘%0::%1’. Cannot find " "type with name ‘%2’.", compiler, - expr->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + expr->getBeginLoc () +#else + expr->getLocStart () +#endif + ) << gir_manager.get_c_name_for_type (static_instance_info) << g_base_info_get_name (signal_info) << g_base_info_get_name (&expected_type_info) @@ -1086,7 +1110,13 @@ _check_signal_callback_type (const Expr *expr, /* TODO: Emit expected type of signal callback? */ Debug::emit_error ("Incorrect return type from signal handler " "for signal ‘%0::%1’. Expected ‘%2’ but saw " - "‘%3’.", compiler, expr->getLocStart ()) + "‘%3’.", compiler, +#ifdef HAVE_LLVM_8_0 + expr->getBeginLoc () +#else + expr->getLocStart () +#endif + ) << gir_manager.get_c_name_for_type (static_instance_info) << g_base_info_get_name (signal_info) << expected_type.getAsString () @@ -1246,7 +1276,13 @@ _check_gsignal_callback_type (const CallExpr &call, Debug::emit_warning ("Non-string literal passed to signal " "name parameter. This is not an error " "but is highly unusual.", - compiler, signal_name_arg->getLocStart ()); + compiler, +#ifdef HAVE_LLVM_8_0 + signal_name_arg->getBeginLoc () +#else + signal_name_arg->getLocStart () +#endif + ); return false; } @@ -1285,7 +1321,12 @@ _check_gsignal_callback_type (const CallExpr &call, "%1() to the specific class defining the " "signal. Ensure a GIR file defining that " "class is loaded.", compiler, - call.getLocStart ()) +#ifdef HAVE_LLVM_8_0 + call.getBeginLoc () +#else + call.getLocStart () +#endif + ) << signal_name << func_info->func_name << gobject_arg->getSourceRange () @@ -1316,7 +1357,13 @@ _check_gsignal_callback_type (const CallExpr &call, "typecast to the GObject parameter of " "%2() to the specific class defining the " "signal. Ensure a GIR file defining that " - "class is loaded.", compiler, call.getLocStart ()) + "class is loaded.", compiler, +#ifdef HAVE_LLVM_8_0 + call.getBeginLoc () +#else + call.getLocStart () +#endif + ) << signal_name << gir_manager.get_c_name_for_type (dynamic_instance_info) << func_info->func_name diff --git a/clang-plugin/gvariant-checker.cpp b/clang-plugin/gvariant-checker.cpp index ac539a2..1557235 100644 --- a/clang-plugin/gvariant-checker.cpp +++ b/clang-plugin/gvariant-checker.cpp @@ -322,7 +322,12 @@ _consume_variadic_argument (QualType expected_type, if (*args_begin == *args_end) { Debug::emit_error ("Expected a GVariant variadic argument of " "type %0 but there wasn’t one.", compiler, - format_arg_str->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + format_arg_str->getBeginLoc () +#else + format_arg_str->getLocStart () +#endif + ) << expected_type; return false; @@ -351,7 +356,12 @@ _consume_variadic_argument (QualType expected_type, expected_type->isPointerType ()) { Debug::emit_error ("Expected a GVariant variadic argument of " "type %0 but saw NULL instead.", compiler, - arg->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + arg->getBeginLoc () +#else + arg->getLocStart () +#endif + ) << expected_type; return false; @@ -367,7 +377,13 @@ _consume_variadic_argument (QualType expected_type, "argument of type %0 but saw one " "of type %1. These types are not " "compatible on every architecture.", - compiler, arg->getLocStart ()) + compiler, +#ifdef HAVE_LLVM_8_0 + arg->getBeginLoc () +#else + arg->getLocStart () +#endif + ) << expected_type << actual_type; @@ -376,7 +392,12 @@ _consume_variadic_argument (QualType expected_type, Debug::emit_error ("Expected a GVariant variadic " "argument of type %0 but saw one " "of type %1.", compiler, - arg->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + arg->getBeginLoc () +#else + arg->getLocStart () +#endif + ) << expected_type << actual_type; @@ -455,7 +476,12 @@ _check_basic_type_string (const gchar **type_str, default: Debug::emit_error ("Expected a GVariant basic type string but " "saw ‘%0’.", compiler, - format_arg_str->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + format_arg_str->getBeginLoc () +#else + format_arg_str->getLocStart () +#endif + ) << std::string (1, **type_str); return false; @@ -573,7 +599,12 @@ _check_type_string (const gchar **type_str, Debug::emit_error ("Invalid GVariant type string: " "tuple did not end with ‘)’.", compiler, - format_arg_str->getLocStart ()); +#ifdef HAVE_LLVM_8_0 + format_arg_str->getBeginLoc () +#else + format_arg_str->getLocStart () +#endif + ); return false; } @@ -593,7 +624,12 @@ _check_type_string (const gchar **type_str, "Invalid GVariant type string: dict did not " "contain exactly two elements.", compiler, - format_arg_str->getLocStart ()); +#ifdef HAVE_LLVM_8_0 + format_arg_str->getBeginLoc () +#else + format_arg_str->getLocStart () +#endif + ); return false; } else if (!_check_basic_type_string (type_str, args_begin, args_end, @@ -608,7 +644,12 @@ _check_type_string (const gchar **type_str, "Invalid GVariant type string: dict did not " "contain exactly two elements.", compiler, - format_arg_str->getLocStart ()); +#ifdef HAVE_LLVM_8_0 + format_arg_str->getBeginLoc () +#else + format_arg_str->getLocStart () +#endif + ); return false; } else if (!_check_type_string (type_str, args_begin, args_end, flags, compiler, @@ -622,14 +663,24 @@ _check_type_string (const gchar **type_str, "Invalid GVariant type string: dict " "did not end with ‘}’.", compiler, - format_arg_str->getLocStart ()); +#ifdef HAVE_LLVM_8_0 + format_arg_str->getBeginLoc () +#else + format_arg_str->getLocStart () +#endif + ); return false; } else if (**type_str != '}') { Debug::emit_error ( "Invalid GVariant type string: dict " "contains more than two elements.", compiler, - format_arg_str->getLocStart ()); +#ifdef HAVE_LLVM_8_0 + format_arg_str->getBeginLoc () +#else + format_arg_str->getLocStart () +#endif + ); return false; } @@ -741,7 +792,12 @@ _check_basic_format_string (const gchar **format_str, "convenience operator ‘^’ was not followed by " "a recognized convenience conversion.", compiler, - format_arg_str->getLocStart ()); +#ifdef HAVE_LLVM_8_0 + format_arg_str->getBeginLoc () +#else + format_arg_str->getLocStart () +#endif + ); return false; } #undef CONVENIENCE_FORMAT @@ -823,7 +879,12 @@ _check_format_string (const gchar **format_str, "Invalid GVariant format string: tuple " "did not end with ‘)’.", compiler, - format_arg_str->getLocStart ()); +#ifdef HAVE_LLVM_8_0 + format_arg_str->getBeginLoc () +#else + format_arg_str->getLocStart () +#endif + ); return false; } @@ -838,7 +899,12 @@ _check_format_string (const gchar **format_str, "Invalid GVariant format string: dict did not " "contain exactly two elements.", compiler, - format_arg_str->getLocStart ()); +#ifdef HAVE_LLVM_8_0 + format_arg_str->getBeginLoc () +#else + format_arg_str->getLocStart () +#endif + ); return false; } else if (!_check_basic_format_string (format_str, args_begin, args_end, @@ -854,7 +920,12 @@ _check_format_string (const gchar **format_str, "Invalid GVariant format string: dict did not " "contain exactly two elements.", compiler, - format_arg_str->getLocStart ()); +#ifdef HAVE_LLVM_8_0 + format_arg_str->getBeginLoc () +#else + format_arg_str->getLocStart () +#endif + ); return false; } else if (!_check_format_string (format_str, args_begin, args_end, @@ -869,14 +940,24 @@ _check_format_string (const gchar **format_str, "Invalid GVariant format string: dict " "did not end with ‘}’.", compiler, - format_arg_str->getLocStart ()); +#ifdef HAVE_LLVM_8_0 + format_arg_str->getBeginLoc () +#else + format_arg_str->getLocStart () +#endif + ); return false; } else if (**format_str != '}') { Debug::emit_error ( "Invalid GVariant format string: dict " "contains more than two elements.", compiler, - format_arg_str->getLocStart ()); +#ifdef HAVE_LLVM_8_0 + format_arg_str->getBeginLoc () +#else + format_arg_str->getLocStart () +#endif + ); return false; } @@ -996,7 +1077,12 @@ _check_gvariant_format_param (const CallExpr& call, "Cannot check format string correctness. Instead " "of a non-literal format string, use GVariantBuilder.", compiler, - format_arg->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + format_arg->getBeginLoc () +#else + format_arg->getLocStart () +#endif + ) << func.getNameAsString (); return false; } @@ -1046,7 +1132,13 @@ _check_gvariant_format_param (const CallExpr& call, "with unpaired arguments. If using multiple " "format strings, they should be enclosed in " "brackets to create a tuple (e.g. ‘(%1)’).", - compiler, format_arg_str->getLocStart ()) + compiler, +#ifdef HAVE_LLVM_8_0 + format_arg_str->getBeginLoc () +#else + format_arg_str->getLocStart () +#endif + ) << format_str << whole_format_str; @@ -1076,7 +1168,13 @@ _check_gvariant_format_param (const CallExpr& call, "(or other valid) GVariant format " "string should be added to the " "format argument to use it.", - compiler, arg->getLocStart ()) + compiler, +#ifdef HAVE_LLVM_8_0 + arg->getBeginLoc () +#else + arg->getLocStart () +#endif + ) << arg->getType () << error_format_str; } else { @@ -1090,7 +1188,13 @@ _check_gvariant_format_param (const CallExpr& call, "type, so the argument must be " "serialized to a " "GVariant-representable type first.", - compiler, arg->getLocStart ()) + compiler, +#ifdef HAVE_LLVM_8_0 + arg->getBeginLoc () +#else + arg->getLocStart () +#endif + ) << arg->getType (); } diff --git a/clang-plugin/nullability-checker.cpp b/clang-plugin/nullability-checker.cpp index 1a38e34..d7dfaa9 100644 --- a/clang-plugin/nullability-checker.cpp +++ b/clang-plugin/nullability-checker.cpp @@ -118,7 +118,7 @@ NullabilityVisitor::TraverseFunctionDecl (FunctionDecl* func) DEBUG ("nonnull attribute indices:"); for (NonNullAttr::args_iterator it = nonnull_attr->args_begin (), ie = nonnull_attr->args_end (); it != ie; ++it) { - DEBUG ("\t" << *it); + DEBUG ("\t" << it->getSourceIndex ()); } } else { DEBUG ("No nonnull attribute."); @@ -236,7 +236,12 @@ NullabilityVisitor::TraverseFunctionDecl (FunctionDecl* func) "annotation on the ‘%0’ parameter " "of function %1().", this->_compiler, - parm_decl->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + parm_decl->getBeginLoc () +#else + parm_decl->getLocStart () +#endif + ) << parm_decl->getNameAsString () << func->getNameAsString (); } else if (has_nullable && has_assertion) { @@ -246,7 +251,12 @@ NullabilityVisitor::TraverseFunctionDecl (FunctionDecl* func) "non-NULL precondition assertion on the ‘%0’ " "parameter of function %1().", this->_compiler, - parm_decl->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + parm_decl->getBeginLoc () +#else + parm_decl->getLocStart () +#endif + ) << parm_decl->getNameAsString () << func->getNameAsString (); } else if (!has_nullable && !has_assertion) { @@ -259,7 +269,12 @@ NullabilityVisitor::TraverseFunctionDecl (FunctionDecl* func) "(already has a nonnull attribute or " "no non-NULL precondition assertion).", this->_compiler, - parm_decl->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + parm_decl->getBeginLoc () +#else + parm_decl->getLocStart () +#endif + ) << parm_decl->getNameAsString () << func->getNameAsString (); break; @@ -270,7 +285,12 @@ NullabilityVisitor::TraverseFunctionDecl (FunctionDecl* func) "non-NULL precondition assertion on " "the ‘%0’ parameter of function %1().", this->_compiler, - parm_decl->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + parm_decl->getBeginLoc () +#else + parm_decl->getLocStart () +#endif + ) << parm_decl->getNameAsString () << func->getNameAsString (); break; @@ -283,7 +303,12 @@ NullabilityVisitor::TraverseFunctionDecl (FunctionDecl* func) "(optional) or (allow-none) " "annotation).", this->_compiler, - parm_decl->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + parm_decl->getBeginLoc () +#else + parm_decl->getLocStart () +#endif + ) << parm_decl->getNameAsString () << func->getNameAsString (); break; @@ -296,7 +321,12 @@ NullabilityVisitor::TraverseFunctionDecl (FunctionDecl* func) "non-NULL precondition annotation on the ‘%0’ " "parameter of function %1().", this->_compiler, - parm_decl->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + parm_decl->getBeginLoc () +#else + parm_decl->getLocStart () +#endif + ) << parm_decl->getNameAsString () << func->getNameAsString (); } else if (has_nonnull == MAYBE && has_assertion) { @@ -307,7 +337,12 @@ NullabilityVisitor::TraverseFunctionDecl (FunctionDecl* func) "parameter of function %1() (already has a " "non-NULL precondition assertion).", this->_compiler, - parm_decl->getLocStart ()) +#ifdef HAVE_LLVM_8_0 + parm_decl->getBeginLoc () +#else + parm_decl->getLocStart () +#endif + ) << parm_decl->getNameAsString () << func->getNameAsString (); } diff --git a/clang-plugin/plugin.cpp b/clang-plugin/plugin.cpp index a2544db..1a94e0f 100644 --- a/clang-plugin/plugin.cpp +++ b/clang-plugin/plugin.cpp @@ -23,7 +23,11 @@ #include "config.h" #include <clang/Frontend/FrontendPluginRegistry.h> +#ifdef HAVE_LLVM_8_0 +#include <clang/StaticAnalyzer/Frontend/CheckerRegistry.h> +#else #include <clang/StaticAnalyzer/Core/CheckerRegistry.h> +#endif #include <clang/AST/AST.h> #include <clang/AST/ASTConsumer.h> #include <clang/Frontend/CompilerInstance.h> @@ -69,7 +73,6 @@ protected: * of the ASTConsumer. The TartanAction object is destroyed immediately * after this function call returns, so must be careful not to retain * state which is needed by the consumers. */ -#ifdef HAVE_LLVM_3_6 std::unique_ptr<ASTConsumer> CreateASTConsumer (CompilerInstance &compiler, llvm::StringRef in_file) { @@ -118,39 +121,6 @@ protected: return llvm::make_unique<MultiplexConsumer> (std::move (consumers)); } -#else /* if !HAVE_LLVM_3_6 */ - ASTConsumer * - CreateASTConsumer (CompilerInstance &compiler, llvm::StringRef in_file) - { - std::vector<ASTConsumer*> consumers; - - /* Annotaters. */ - consumers.push_back ( - new GirAttributesConsumer (global_gir_manager)); - consumers.push_back ( - new GAssertAttributesConsumer ()); - - /* Checkers. */ - consumers.push_back ( - new NullabilityConsumer (compiler, - global_gir_manager, - this->_disabled_checkers)); - consumers.push_back ( - new GVariantConsumer (compiler, - global_gir_manager, - this->_disabled_checkers)); - consumers.push_back ( - new GSignalConsumer (compiler, - global_gir_manager, - this->_disabled_checkers)); - consumers.push_back ( - new GirAttributesChecker (compiler, - global_gir_manager, - this->_disabled_checkers)); - - return new MultiplexConsumer (consumers); - } -#endif /* !HAVE_LLVM_3_6 */ private: bool @@ -375,7 +345,11 @@ void clang_registerCheckers (ento::CheckerRegistry ®istry); extern "C" void clang_registerCheckers (ento::CheckerRegistry ®istry) { registry.addChecker<GErrorChecker> ("tartan.GErrorChecker", - "Check GError API usage"); + "Check GError API usage" +#ifdef HAVE_LLVM_8_0 + , "http://www.freedesktop.org/software/tartan/" +#endif + ); } extern "C" diff --git a/clang-plugin/type-manager.cpp b/clang-plugin/type-manager.cpp index ae6593d..46c7319 100644 --- a/clang-plugin/type-manager.cpp +++ b/clang-plugin/type-manager.cpp @@ -47,16 +47,8 @@ TypeManager::find_type_by_name (const std::string name) return (*cached).second; } -#ifdef HAVE_LLVM_3_8 for (SmallVectorImpl<Type *>::const_iterator it = this->_context.getTypes ().begin (), ie = this->_context.getTypes ().end (); it != ie; ++it) { -#elif HAVE_LLVM_3_5 - for (SmallVectorImpl<Type *>::const_iterator it = this->_context.types ().begin (), - ie = this->_context.types ().end (); it != ie; ++it) { -#else /* if !HAVE_LLVM_3_5 */ - for (ASTContext::const_type_iterator it = this->_context.types_begin (), - ie = this->_context.types_end (); it != ie; ++it) { -#endif /* !HAVE_LLVM_3_5 */ const Type *t = *it; const TypedefType *tt = t->getAs<TypedefType> (); diff --git a/configure.ac b/configure.ac index ad6bef4..ab6e12b 100644 --- a/configure.ac +++ b/configure.ac @@ -30,7 +30,7 @@ LT_INIT([]) PKG_PROG_PKG_CONFIG # Requirements -LLVM_REQS=3.5 +LLVM_REQS=7.0 GLIB_REQS=2.38 # TODO GIO_REQS=2.38 # TODO GIR_REQS=1.38.0 # TODO @@ -56,17 +56,17 @@ AS_IF([test $LLVM_CONFIG = "failed"],[ AC_MSG_CHECKING([for LLVM]) # LLVM_REQS is either (e.g.) 3.5, 3.6svn or 3.4.2 -req_major=`echo $LLVM_REQS | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\(\.[[0-9]]*\)\?\(svn\)\?/\1/'` -req_minor=`echo $LLVM_REQS | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\(\.[[0-9]]*\)\?\(svn\)\?/\2/'` +req_major=`echo $LLVM_REQS | sed -E 's/([[0-9]]*)\.([[0-9]]*)(\.[[0-9]]*)?(svn)?/\1/'` +req_minor=`echo $LLVM_REQS | sed -E 's/([[0-9]]*)\.([[0-9]]*)(\.[[0-9]]*)?(svn)?/\2/'` llvm_version=`$LLVM_CONFIG --version` -major=`echo $llvm_version | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\(\.[[0-9]]*\)\?\(svn\)\?/\1/'` -minor=`echo $llvm_version | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\(\.[[0-9]]*\)\?\(svn\)\?/\2/'` +major=`echo $llvm_version | sed -E 's/([[0-9]]*)\.([[0-9]]*)(\.[[0-9]]*)?(svn)?/\1/'` +minor=`echo $llvm_version | sed -E 's/([[0-9]]*)\.([[0-9]]*)(\.[[0-9]]*)?(svn)?/\2/'` AS_IF([test "$major" -gt "$req_major" -o \( "$major" -eq "$req_major" -a "$minor" -ge "$req_minor" \)],[ - LLVM_CPPFLAGS=`$LLVM_CONFIG --cppflags` - LLVM_CXXFLAGS=`$LLVM_CONFIG --cxxflags` + LLVM_CPPFLAGS=`$LLVM_CONFIG --cppflags | sed -e 's,-I/,-isystem /,' | sed -e 's,-isystem /usr/include,-I/usr/include,'` + LLVM_CXXFLAGS=`$LLVM_CONFIG --cxxflags | sed -e 's,-I/,-isystem /,' | sed -e 's,-isystem /usr/include,-I/usr/include,'` LLVM_LDFLAGS=`$LLVM_CONFIG --ldflags` # Don't link against the LLVM libs because they're huge. All the symbols # will be available when the plugin is loaded anyway. @@ -88,23 +88,11 @@ AC_DEFINE_UNQUOTED([LLVM_CONFIG_VERSION],"$llvm_version", [Configured LLVM version]) # LLVM-specific version definitions -AS_IF([test "$major" -gt 3 -o "$major" -eq 3 -a "$minor" -ge 5],[ - AC_DEFINE([HAVE_LLVM_3_5], [1], [Whether LLVM ≥ 3.5 is available]) +AS_IF([test "$major" -ge 8],[ + AC_DEFINE([HAVE_LLVM_8_0], [1], [Whether LLVM ≥ 8.0 is available]) ]) -AS_IF([test "$major" -gt 3 -o "$major" -eq 3 -a "$minor" -ge 6],[ - AC_DEFINE([HAVE_LLVM_3_6], [1], [Whether LLVM ≥ 3.6 is available]) -]) -AS_IF([test "$major" -gt 3 -o "$major" -eq 3 -a "$minor" -ge 7],[ - AC_DEFINE([HAVE_LLVM_3_7], [1], [Whether LLVM ≥ 3.7 is available]) -]) -AS_IF([test "$major" -gt 3 -o "$major" -eq 3 -a "$minor" -ge 8],[ - AC_DEFINE([HAVE_LLVM_3_8], [1], [Whether LLVM ≥ 3.8 is available]) -]) -AS_IF([test "$major" -gt 3 -o "$major" -eq 3 -a "$minor" -ge 9],[ - AC_DEFINE([HAVE_LLVM_3_9], [1], [Whether LLVM ≥ 3.9 is available]) -]) -AS_IF([test "$major" -gt 4 -o "$major" -eq 4 -a "$minor" -ge 0],[ - AC_DEFINE([HAVE_LLVM_4_0], [1], [Whether LLVM ≥ 4.0 is available]) +AS_IF([test "$major" -ge 9],[ + AC_DEFINE([HAVE_LLVM_9_0], [1], [Whether LLVM ≥ 9.0 is available]) ]) # Clang dependency (e.g. the clang-devel package on Fedora) @@ -125,7 +113,7 @@ AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],"$GETTEXT_PACKAGE", IT_PROG_INTLTOOL([0.40.0]) # Code coverage for unit tests -AX_CODE_COVERAGE +TARTAN_CODE_COVERAGE # Compiler warnings AX_COMPILER_FLAGS diff --git a/m4/ax_append_compile_flags.m4 b/m4/ax_append_compile_flags.m4 index 2bb27ef..9c85635 100644 --- a/m4/ax_append_compile_flags.m4 +++ b/m4/ax_append_compile_flags.m4 @@ -1,6 +1,6 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html -# =========================================================================== +# ============================================================================ +# https://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html +# ============================================================================ # # SYNOPSIS # @@ -30,33 +30,12 @@ # # Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> # -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see <http://www.gnu.org/licenses/>. -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. -#serial 5 +#serial 7 AC_DEFUN([AX_APPEND_COMPILE_FLAGS], [AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG]) diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4 index 08f2e07..dd6d8b6 100644 --- a/m4/ax_append_flag.m4 +++ b/m4/ax_append_flag.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_append_flag.html +# https://www.gnu.org/software/autoconf-archive/ax_append_flag.html # =========================================================================== # # SYNOPSIS @@ -23,33 +23,12 @@ # Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> # Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> # -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see <http://www.gnu.org/licenses/>. -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. -#serial 6 +#serial 8 AC_DEFUN([AX_APPEND_FLAG], [dnl diff --git a/m4/ax_append_link_flags.m4 b/m4/ax_append_link_flags.m4 index fd70fc7..99b9fa5 100644 --- a/m4/ax_append_link_flags.m4 +++ b/m4/ax_append_link_flags.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_append_link_flags.html +# https://www.gnu.org/software/autoconf-archive/ax_append_link_flags.html # =========================================================================== # # SYNOPSIS @@ -28,33 +28,12 @@ # # Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> # -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see <http://www.gnu.org/licenses/>. -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. -#serial 5 +#serial 7 AC_DEFUN([AX_APPEND_LINK_FLAGS], [AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 index ca36397..bd753b3 100644 --- a/m4/ax_check_compile_flag.m4 +++ b/m4/ax_check_compile_flag.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html # =========================================================================== # # SYNOPSIS @@ -29,33 +29,12 @@ # Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> # Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> # -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see <http://www.gnu.org/licenses/>. -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. -#serial 4 +#serial 6 AC_DEFUN([AX_CHECK_COMPILE_FLAG], [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF diff --git a/m4/ax_check_enable_debug.m4 b/m4/ax_check_enable_debug.m4 index f99d75f..7bc7710 100644 --- a/m4/ax_check_enable_debug.m4 +++ b/m4/ax_check_enable_debug.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_check_enable_debug.html +# https://www.gnu.org/software/autoconf-archive/ax_check_enable_debug.html # =========================================================================== # # SYNOPSIS @@ -42,7 +42,7 @@ # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. -#serial 5 +#serial 9 AC_DEFUN([AX_CHECK_ENABLE_DEBUG],[ AC_BEFORE([$0],[AC_PROG_CC])dnl @@ -65,8 +65,8 @@ AC_DEFUN([AX_CHECK_ENABLE_DEBUG],[ m4_define(ax_disable_debug_vars,[m4_normalize(ifelse([$3],,[NDEBUG],[$3]))]) AC_ARG_ENABLE(debug, - [AS_HELP_STRING([--enable-debug=]@<:@yes/info/profile/no@:>@,[compile with debugging])], - [],enable_debug=$ax_enable_debug_default) + [AS_HELP_STRING([--enable-debug=]@<:@yes/info/profile/no@:>@,[compile with debugging])], + [],enable_debug=$ax_enable_debug_default) # empty mean debug yes AS_IF([test "x$enable_debug" = "x"], @@ -75,50 +75,50 @@ AC_DEFUN([AX_CHECK_ENABLE_DEBUG],[ # case of debug AS_CASE([$enable_debug], [yes],[ - AC_MSG_RESULT(yes) - CFLAGS="${CFLAGS} -g -O0" - CXXFLAGS="${CXXFLAGS} -g -O0" - FFLAGS="${FFLAGS} -g -O0" - FCFLAGS="${FCFLAGS} -g -O0" - OBJCFLAGS="${OBJCFLAGS} -g -O0" + AC_MSG_RESULT(yes) + CFLAGS="${CFLAGS} -g -O0" + CXXFLAGS="${CXXFLAGS} -g -O0" + FFLAGS="${FFLAGS} -g -O0" + FCFLAGS="${FCFLAGS} -g -O0" + OBJCFLAGS="${OBJCFLAGS} -g -O0" ], [info],[ - AC_MSG_RESULT(info) - CFLAGS="${CFLAGS} -g" - CXXFLAGS="${CXXFLAGS} -g" - FFLAGS="${FFLAGS} -g" - FCFLAGS="${FCFLAGS} -g" - OBJCFLAGS="${OBJCFLAGS} -g" + AC_MSG_RESULT(info) + CFLAGS="${CFLAGS} -g" + CXXFLAGS="${CXXFLAGS} -g" + FFLAGS="${FFLAGS} -g" + FCFLAGS="${FCFLAGS} -g" + OBJCFLAGS="${OBJCFLAGS} -g" ], [profile],[ - AC_MSG_RESULT(profile) - CFLAGS="${CFLAGS} -g -pg" - CXXFLAGS="${CXXFLAGS} -g -pg" - FFLAGS="${FFLAGS} -g -pg" - FCFLAGS="${FCFLAGS} -g -pg" - OBJCFLAGS="${OBJCFLAGS} -g -pg" - LDFLAGS="${LDFLAGS} -pg" + AC_MSG_RESULT(profile) + CFLAGS="${CFLAGS} -g -pg" + CXXFLAGS="${CXXFLAGS} -g -pg" + FFLAGS="${FFLAGS} -g -pg" + FCFLAGS="${FCFLAGS} -g -pg" + OBJCFLAGS="${OBJCFLAGS} -g -pg" + LDFLAGS="${LDFLAGS} -pg" ], [ - AC_MSG_RESULT(no) - dnl Ensure AC_PROG_CC/CXX/F77/FC/OBJC will not enable debug flags - dnl by setting any unset environment flag variables - AS_IF([test "x${CFLAGS+set}" != "xset"], - [CFLAGS=""]) - AS_IF([test "x${CXXFLAGS+set}" != "xset"], - [CXXFLAGS=""]) - AS_IF([test "x${FFLAGS+set}" != "xset"], - [FFLAGS=""]) - AS_IF([test "x${FCFLAGS+set}" != "xset"], - [FCFLAGS=""]) - AS_IF([test "x${OBJCFLAGS+set}" != "xset"], - [OBJCFLAGS=""]) + AC_MSG_RESULT(no) + dnl Ensure AC_PROG_CC/CXX/F77/FC/OBJC will not enable debug flags + dnl by setting any unset environment flag variables + AS_IF([test "x${CFLAGS+set}" != "xset"], + [CFLAGS=""]) + AS_IF([test "x${CXXFLAGS+set}" != "xset"], + [CXXFLAGS=""]) + AS_IF([test "x${FFLAGS+set}" != "xset"], + [FFLAGS=""]) + AS_IF([test "x${FCFLAGS+set}" != "xset"], + [FCFLAGS=""]) + AS_IF([test "x${OBJCFLAGS+set}" != "xset"], + [OBJCFLAGS=""]) ]) dnl Define various variables if debugging is disabled. dnl assert.h is a NOP if NDEBUG is defined, so define it by default. AS_IF([test "x$enable_debug" = "xyes"], - [m4_map_args_w(ax_enable_debug_vars, [AC_DEFINE(], [,,[Define if debugging is enabled])])], - [m4_map_args_w(ax_disable_debug_vars, [AC_DEFINE(], [,,[Define if debugging is disabled])])]) + [m4_map_args_w(ax_enable_debug_vars, [AC_DEFINE(], [,[1],[Define if debugging is enabled])])], + [m4_map_args_w(ax_disable_debug_vars, [AC_DEFINE(], [,[1],[Define if debugging is disabled])])]) ax_enable_debug=$enable_debug ]) diff --git a/m4/ax_check_link_flag.m4 b/m4/ax_check_link_flag.m4 index eb01a6c..03a30ce 100644 --- a/m4/ax_check_link_flag.m4 +++ b/m4/ax_check_link_flag.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html +# https://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html # =========================================================================== # # SYNOPSIS @@ -29,33 +29,12 @@ # Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> # Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> # -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see <http://www.gnu.org/licenses/>. -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. -#serial 4 +#serial 6 AC_DEFUN([AX_CHECK_LINK_FLAG], [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF diff --git a/m4/ax_compiler_flags_cxxflags.m4 b/m4/ax_compiler_flags_cxxflags.m4 index d702aac..3067d9b 100644 --- a/m4/ax_compiler_flags_cxxflags.m4 +++ b/m4/ax_compiler_flags_cxxflags.m4 @@ -1,6 +1,6 @@ -# ============================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_compiler_flags_cxxflags.html -# ============================================================================== +# =============================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_compiler_flags_cxxflags.html +# =============================================================================== # # SYNOPSIS # @@ -26,7 +26,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 8 +#serial 10 AC_DEFUN([AX_COMPILER_FLAGS_CXXFLAGS],[ AC_REQUIRE([AC_PROG_SED]) @@ -51,6 +51,13 @@ AC_DEFUN([AX_COMPILER_FLAGS_CXXFLAGS],[ ax_compiler_flags_test="" ]) + # Check that -Wno-suggest-attribute=format is supported + AX_CHECK_COMPILE_FLAG([-Wno-suggest-attribute=format],[ + ax_compiler_no_suggest_attribute_flags="-Wno-suggest-attribute=format" + ],[ + ax_compiler_no_suggest_attribute_flags="" + ]) + # Base flags AX_APPEND_COMPILE_FLAGS([ dnl -fno-strict-aliasing dnl @@ -104,7 +111,7 @@ AC_DEFUN([AX_COMPILER_FLAGS_CXXFLAGS],[ AX_APPEND_FLAG([-Werror],ax_warn_cxxflags_variable) AX_APPEND_COMPILE_FLAGS([ dnl - -Wno-suggest-attribute=format dnl + [$ax_compiler_no_suggest_attribute_flags] dnl ],ax_warn_cxxflags_variable,[$ax_compiler_flags_test]) ]) diff --git a/m4/ax_compiler_flags_gir.m4 b/m4/ax_compiler_flags_gir.m4 index 4a854f0..5b4924a 100644 --- a/m4/ax_compiler_flags_gir.m4 +++ b/m4/ax_compiler_flags_gir.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_compiler_flags_gir.html +# https://www.gnu.org/software/autoconf-archive/ax_compiler_flags_gir.html # =========================================================================== # # SYNOPSIS @@ -26,7 +26,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 5 +#serial 6 AC_DEFUN([AX_COMPILER_FLAGS_GIR],[ AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) diff --git a/m4/ax_compiler_flags_ldflags.m4 b/m4/ax_compiler_flags_ldflags.m4 index fd7974e..976d119 100644 --- a/m4/ax_compiler_flags_ldflags.m4 +++ b/m4/ax_compiler_flags_ldflags.m4 @@ -1,6 +1,6 @@ -# ============================================================================= -# http://www.gnu.org/software/autoconf-archive/ax_compiler_flags_ldflags.html -# ============================================================================= +# ============================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_compiler_flags_ldflags.html +# ============================================================================== # # SYNOPSIS # @@ -19,13 +19,14 @@ # LICENSE # # Copyright (c) 2014, 2015 Philip Withnall <philip@tecnocode.co.uk> +# Copyright (c) 2017, 2018 Reini Urban <rurban@cpan.org> # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 7 +#serial 9 AC_DEFUN([AX_COMPILER_FLAGS_LDFLAGS],[ AX_REQUIRE_DEFINED([AX_APPEND_LINK_FLAGS]) @@ -48,7 +49,25 @@ AC_DEFUN([AX_COMPILER_FLAGS_LDFLAGS],[ ax_compiler_flags_test="" ]) - # macOS linker does not have --as-needed + AX_CHECK_LINK_FLAG([-Wl,--as-needed], [ + AX_APPEND_LINK_FLAGS([-Wl,--as-needed], + [AM_LDFLAGS],[$ax_compiler_flags_test]) + ]) + AX_CHECK_LINK_FLAG([-Wl,-z,relro], [ + AX_APPEND_LINK_FLAGS([-Wl,-z,relro], + [AM_LDFLAGS],[$ax_compiler_flags_test]) + ]) + AX_CHECK_LINK_FLAG([-Wl,-z,now], [ + AX_APPEND_LINK_FLAGS([-Wl,-z,now], + [AM_LDFLAGS],[$ax_compiler_flags_test]) + ]) + AX_CHECK_LINK_FLAG([-Wl,-z,noexecstack], [ + AX_APPEND_LINK_FLAGS([-Wl,-z,noexecstack], + [AM_LDFLAGS],[$ax_compiler_flags_test]) + ]) + # textonly, retpolineplt not yet + + # macOS and cygwin linker do not have --as-needed AX_CHECK_LINK_FLAG([-Wl,--no-as-needed], [ ax_compiler_flags_as_needed_option="-Wl,--no-as-needed" ], [ diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4 index b61fcb6..9e9eaed 100644 --- a/m4/ax_cxx_compile_stdcxx.m4 +++ b/m4/ax_cxx_compile_stdcxx.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html # =========================================================================== # # SYNOPSIS @@ -33,19 +33,18 @@ # Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com> # Copyright (c) 2015 Paul Norman <penorman@mac.com> # Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu> -# Copyright (c) 2016 Krzesimir Nowak <qdlacz@gmail.com> +# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com> # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 6 +#serial 10 dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro dnl (serial version number 13). -AX_REQUIRE_DEFINED([AC_MSG_WARN]) AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], [$1], [14], [ax_cxx_compile_alternatives="14 1y"], @@ -61,14 +60,6 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) AC_LANG_PUSH([C++])dnl ac_success=no - AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, - ax_cv_cxx_compile_cxx$1, - [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], - [ax_cv_cxx_compile_cxx$1=yes], - [ax_cv_cxx_compile_cxx$1=no])]) - if test x$ax_cv_cxx_compile_cxx$1 = xyes; then - ac_success=yes - fi m4_if([$2], [noext], [], [dnl if test x$ac_success = xno; then @@ -139,7 +130,6 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [define if the compiler supports basic C++$1 syntax]) fi AC_SUBST(HAVE_CXX$1) - m4_if([$1], [17], [AC_MSG_WARN([C++17 is not yet standardized, so the checks may change in incompatible ways anytime])]) ]) @@ -587,20 +577,12 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ #error "This is not a C++ compiler" -#elif __cplusplus <= 201402L +#elif __cplusplus < 201703L #error "This is not a C++17 compiler" #else -#if defined(__clang__) - #define REALLY_CLANG -#else - #if defined(__GNUC__) - #define REALLY_GCC - #endif -#endif - #include <initializer_list> #include <utility> #include <type_traits> @@ -608,16 +590,12 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ namespace cxx17 { -#if !defined(REALLY_CLANG) namespace test_constexpr_lambdas { - // TODO: test it with clang++ from git - constexpr int foo = [](){return 42;}(); } -#endif // !defined(REALLY_CLANG) namespace test::nested_namespace::definitions { @@ -852,12 +830,9 @@ namespace cxx17 } -#if !defined(REALLY_CLANG) namespace test_template_argument_deduction_for_class_templates { - // TODO: test it with clang++ from git - template <typename T1, typename T2> struct pair { @@ -876,7 +851,6 @@ namespace cxx17 } } -#endif // !defined(REALLY_CLANG) namespace test_non_type_auto_template_parameters { @@ -890,12 +864,9 @@ namespace cxx17 } -#if !defined(REALLY_CLANG) namespace test_structured_bindings { - // TODO: test it with clang++ from git - int arr[2] = { 1, 2 }; std::pair<int, int> pr = { 1, 2 }; @@ -927,14 +898,10 @@ namespace cxx17 const auto [ x3, y3 ] = f3(); } -#endif // !defined(REALLY_CLANG) -#if !defined(REALLY_CLANG) namespace test_exception_spec_type_system { - // TODO: test it with clang++ from git - struct Good {}; struct Bad {}; @@ -952,7 +919,6 @@ namespace cxx17 static_assert (std::is_same_v<Good, decltype(f(g1, g2))>); } -#endif // !defined(REALLY_CLANG) namespace test_inline_variables { @@ -977,6 +943,6 @@ namespace cxx17 } // namespace cxx17 -#endif // __cplusplus <= 201402L +#endif // __cplusplus < 201703L ]]) diff --git a/m4/ax_cxx_compile_stdcxx_11.m4 b/m4/ax_cxx_compile_stdcxx_11.m4 index 0aadeaf..1733fd8 100644 --- a/m4/ax_cxx_compile_stdcxx_11.m4 +++ b/m4/ax_cxx_compile_stdcxx_11.m4 @@ -1,6 +1,6 @@ -# ============================================================================ -# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html -# ============================================================================ +# ============================================================================= +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html +# ============================================================================= # # SYNOPSIS # @@ -33,7 +33,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 17 +#serial 18 AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX]) AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [AX_CXX_COMPILE_STDCXX([11], [$1], [$2])]) diff --git a/m4/ax_generate_changelog.m4 b/m4/ax_generate_changelog.m4 index 71c5fd1..e2f0c54 100644 --- a/m4/ax_generate_changelog.m4 +++ b/m4/ax_generate_changelog.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_generate_changelog.html +# https://www.gnu.org/software/autoconf-archive/ax_generate_changelog.html # =========================================================================== # # SYNOPSIS @@ -52,7 +52,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 2 +#serial 3 AC_DEFUN([AX_GENERATE_CHANGELOG],[ # Find git, defaulting to the 'missing' script so the user gets a nice diff --git a/m4/ax_is_release.m4 b/m4/ax_is_release.m4 index 0892e65..9097ddb 100644 --- a/m4/ax_is_release.m4 +++ b/m4/ax_is_release.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_is_release.html +# https://www.gnu.org/software/autoconf-archive/ax_is_release.html # =========================================================================== # # SYNOPSIS @@ -44,7 +44,7 @@ # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. -#serial 5 +#serial 7 AC_DEFUN([AX_IS_RELEASE],[ AC_BEFORE([AC_INIT],[$0]) @@ -52,7 +52,7 @@ AC_DEFUN([AX_IS_RELEASE],[ m4_case([$1], [git-directory],[ # $is_release = (.git directory does not exist) - AS_IF([test -d ${top_srcdir}/.git],[ax_is_release=no],[ax_is_release=yes]) + AS_IF([test -d ${srcdir}/.git],[ax_is_release=no],[ax_is_release=yes]) ], [minor-version],[ # $is_release = ($minor_version is even) diff --git a/m4/ax_require_defined.m4 b/m4/ax_require_defined.m4 index cae1111..17c3eab 100644 --- a/m4/ax_require_defined.m4 +++ b/m4/ax_require_defined.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_require_defined.html +# https://www.gnu.org/software/autoconf-archive/ax_require_defined.html # =========================================================================== # # SYNOPSIS @@ -30,7 +30,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 1 +#serial 2 AC_DEFUN([AX_REQUIRE_DEFINED], [dnl m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) diff --git a/m4/ax_code_coverage.m4 b/m4/tartan_code_coverage.m4 index a257469..2049603 100644 --- a/m4/ax_code_coverage.m4 +++ b/m4/tartan_code_coverage.m4 @@ -1,10 +1,10 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_code_coverage.html +# https://www.gnu.org/software/autoconf-archive/ax_code_coverage.html # =========================================================================== # # SYNOPSIS # -# AX_CODE_COVERAGE() +# TARTAN_CODE_COVERAGE() # # DESCRIPTION # @@ -21,14 +21,14 @@ # Test also for gcov program and create GCOV variable that could be # substituted. # -# Note that all optimisation flags in CFLAGS must be disabled when code +# Note that all optimization flags in CFLAGS must be disabled when code # coverage is enabled. # # Usage example: # # configure.ac: # -# AX_CODE_COVERAGE +# TARTAN_CODE_COVERAGE # # Makefile.am: # @@ -73,11 +73,11 @@ # General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. +# along with this program. If not, see <https://www.gnu.org/licenses/>. -#serial 20 +#serial 25 -AC_DEFUN([AX_CODE_COVERAGE],[ +AC_DEFUN([TARTAN_CODE_COVERAGE],[ dnl Check for --enable-code-coverage AC_REQUIRE([AC_PROG_SED]) @@ -218,9 +218,12 @@ CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\ $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ --rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) -CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULTS) +CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) CODE_COVERAGE_IGNORE_PATTERN ?= +GITIGNOREFILES ?= +GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) + code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V)) code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY)) code_coverage_v_lcov_cap_0 = @echo " LCOV --capture"\ @@ -250,9 +253,6 @@ code-coverage-capture-hook: '"$CODE_COVERAGE_RULES_CLEAN"' -GITIGNOREFILES ?= -GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) - A''M_DISTCHECK_CONFIGURE_FLAGS ?= A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage diff --git a/scripts/tartan b/scripts/tartan index 85b4105..3dcf012 100755 --- a/scripts/tartan +++ b/scripts/tartan @@ -33,7 +33,7 @@ fi # Vendor-specific clang version 3.6.2-1bo1 (tags/RELEASE_362/final) (based on LLVM 3.6.2) # Target: x86_64-unknown-linux-gnu # Thread model: posix -clang_version=`"$real_clang" --version | head -n1 | sed 's/\([^0-9]*\)\([[0-9]]*\)\.\([[0-9]]*\)\(\.[[0-9]]*\)\?\(svn\)\?\(.*\)/\2.\3/'` +clang_version=`"$real_clang" --version | head -n1 | sed -E 's/([^0-9]*)([0-9]*)\.([0-9]*)(\.[0-9]*)?(svn)?(.*)/\2.\3/'` # Sanity check. if [ "$clang_version" == "" ]; then @@ -58,7 +58,7 @@ elif [ -f "$clang_prefix/lib/tartan/$clang_version/libtartan.so" ]; then # 32-bit installed. plugin_path="$clang_prefix/lib/tartan/$clang_version/libtartan.so" elif [ ! -d "$clang_prefix/lib/tartan/$clang_version/" ]; then - echo "Error: Unsupported version of Clang ‘$clang_version’. Recompile Tartan for this version of Clang, set TARTAN_CC to a supported Clang version, or set TARTAN_PLUGIN to a plugin which supports this version." >& 2 + echo "Error: Unsupported version of Clang ‘${clang_version}’. Recompile Tartan for this version of Clang, set TARTAN_CC to a supported Clang version, or set TARTAN_PLUGIN to a plugin which supports this version." >& 2 exit 2 else echo "Error: Could not find libtartan.so. Set TARTAN_PLUGIN to the absolute path of the Tartan plugin." >& 2 @@ -130,11 +130,15 @@ if [ "$include_plugin_flags" = "1" ] && include_plugin_flags=0 fi -# The -analyzer-checker argument loads all 'tartan.*' static checkers. +# The -analyzer-checker arguments load all 'tartan.*' and 'core.*' static +# checkers. # The -add-plugin argument loads the tartan AST frontend plugin. +# FIXME: in Clang 10.x, add '-analyzer-config silence-checker=core' in order to +# only print Tartan warnings. add_plugin=( "-load" "$plugin_path" \ "-add-plugin" "$plugin_name" \ - "-analyzer-checker" "$plugin_name" ) + "-analyzer-checker" "$plugin_name" \ + "-analyzer-checker" "core" ) if [ "$escape_plugin_flags" = "1" ]; then _add_plugin=() diff --git a/tests/Makefile.am b/tests/Makefile.am index 00c0b4f..75f069f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -3,6 +3,7 @@ # with Tartan (and -Werror). TEST_EXTENSIONS = .c +AM_TESTS_ENVIRONMENT = export abs_top_builddir=$(abs_top_builddir); C_LOG_COMPILER = $(top_srcdir)/tests/wrapper-compiler-errors c_tests = \ diff --git a/tests/gerror-api.c b/tests/gerror-api.c index 6d03b1a..442bf9b 100644 --- a/tests/gerror-api.c +++ b/tests/gerror-api.c @@ -55,16 +55,6 @@ } /* - * warning: Using uninitialized GError - * g_error_free (some_error); - * ^~~~~~~~~~~~~~~~~~~~~~~~~ - */ -{ - GError *some_error; // uninitialised - g_error_free (some_error); -} - -/* * warning: Freeing non-set GError * g_error_free (some_error); * ^~~~~~~~~~~~~~~~~~~~~~~~~ @@ -390,16 +380,6 @@ } /* - * warning: Freeing non-set GError - * g_propagate_error (error, sub_error); - * ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ -{ - GError *sub_error = NULL; - g_propagate_error (error, sub_error); -} - -/* * warning: Freeing already-freed GError * g_propagate_error (error, sub_error); * ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/gsignal-connect.c b/tests/gsignal-connect.c index abbcb94..43e361f 100644 --- a/tests/gsignal-connect.c +++ b/tests/gsignal-connect.c @@ -35,9 +35,6 @@ * Could not check type of handler for signal ‘GObject::notify’. Callback function declaration does not contain parameter types. * (GCallback) object_notify_no_proto_cb, * ^ - * note: expanded from macro 'g_signal_connect' - * g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0) - * ^ */ { GObject *some_object = g_malloc (5); // only checking the type diff --git a/tests/gvariant-iter.c b/tests/gvariant-iter.c index 37865ff..ff36db7 100644 --- a/tests/gvariant-iter.c +++ b/tests/gvariant-iter.c @@ -9,10 +9,12 @@ GVariant *value; gchar *key; + dictionary = g_variant_new_array ((const GVariantType *) "{sv}", NULL, 0); g_variant_iter_init (&iter, dictionary); while (g_variant_iter_loop (&iter, "{sv}", &key, &value)) { /* Something */ } + g_variant_unref (dictionary); } /* @@ -26,10 +28,12 @@ gchar *not_a_value; gchar *key; + dictionary = g_variant_new_array ((const GVariantType *) "{sv}", NULL, 0); g_variant_iter_init (&iter, dictionary); while (g_variant_iter_loop (&iter, "{sv}", &key, ¬_a_value)) { /* Something */ } + g_variant_unref (dictionary); } /* @@ -41,6 +45,7 @@ GVariant *value; gchar *key; + dictionary = g_variant_new_array ((const GVariantType *) "{sv}", NULL, 0); g_variant_iter_init (&iter, dictionary); while (g_variant_iter_next (&iter, "{sv}", &key, &value)) { /* Something */ @@ -48,6 +53,7 @@ g_variant_unref (value); g_free (key); } + g_variant_unref (dictionary); } /* @@ -61,6 +67,7 @@ gchar *not_a_value; gchar *key; + dictionary = g_variant_new_array ((const GVariantType *) "{sv}", NULL, 0); g_variant_iter_init (&iter, dictionary); while (g_variant_iter_next (&iter, "{sv}", &key, ¬_a_value)) { /* Something */ @@ -68,4 +75,5 @@ g_free (not_a_value); g_free (key); } + g_variant_unref (dictionary); } diff --git a/tests/wrapper-compiler-errors b/tests/wrapper-compiler-errors index 8e30771..941024a 100755 --- a/tests/wrapper-compiler-errors +++ b/tests/wrapper-compiler-errors @@ -21,10 +21,10 @@ # asserts there’s no error. input_filename=$1 -temp_dir=`mktemp -d` +temp_dir=`mktemp -d`/${abs_top_builddir} tests_dir=`dirname $0` tartan=${tests_dir}/../scripts/tartan -tartan_plugin=${tests_dir}/../clang-plugin/.libs/libtartan.so +tartan_plugin=${abs_top_builddir}/clang-plugin/.libs/libtartan.so echo "Reading input from ${input_filename}." echo "Using temporary directory ${temp_dir}." @@ -36,7 +36,8 @@ test_status=0 # Before starting, work out the compiler’s system include paths. # Thanks to: http://stackoverflow.com/a/17940271/2931197 system_includes=`echo | cpp -Wp,-v 2>&1 | grep '^[[:space:]]' | \ - sed -e 's/^[[:space:]]*/-isystem/' | tr "\n" ' '` + sed -e 's/^[[:space:]]*/-isystem/' -e 's/ (framework directory)//' | \ + tr "\n" ' '` # Extract the template name. template_name=`head -n 1 "${input_filename}" | \ @@ -46,6 +47,7 @@ template_name=`head -n 1 "${input_filename}" | \ echo "Using template ${template_name}." # Split the input file up into sections, delimiting on ‘/*’ on a line by itself. +mkdir -p ${temp_dir}/${srcdir} tail -n +3 "${input_filename}" > "${temp_dir}/${input_filename}.tail" csplit --keep-files --elide-empty-files --silent \ --prefix="${temp_dir}/${input_filename}_" \ @@ -67,9 +69,9 @@ while [[ -f `printf "${temp_dir}/${input_filename}_%02d.c" ${num}` ]]; do echo " - Outputting to error files ${expected_error_filename} and ${actual_error_filename}." # Wrap the section’s code with a prefix and suffix. - (cat "${template_name}.head.c" + (cat "${srcdir}/${template_name}.head.c" cat "${section_filename}" - cat "${template_name}.tail.c" + cat "${srcdir}/${template_name}.tail.c" ) > $section_filename.tmp mv -f $section_filename.tmp $section_filename @@ -107,20 +109,11 @@ while [[ -f `printf "${temp_dir}/${input_filename}_%02d.c" ${num}` ]]; do while read line do - # Check the string and the string with ‘which’ for - # ‘that’ against the actual errors. This is a hack - # needed to support testing against LLVM 3.4 and 3.5 - # from the same test vectors. - # - # See commit 0743df4033967c18a5009e4f01ccf709f7c06c86 - # for details. + # Check the string against the actual errors. grep -F "${line}" "${actual_error_filename}" >/dev/null - grep_status1=$? + grep_status=$? - grep -F "${line//that/which}" "${actual_error_filename}" >/dev/null - grep_status2=$? - - if [ $grep_status1 -ne 0 -a $grep_status2 -ne 0 ]; then + if [ $grep_status -ne 0 ]; then echo " * Non-matching line:" 1>&2 echo "${line}" 1>&2 grep_failed=1 |