Search code examples
c++11llvmeclipse-cdtinitializer-listtemplate-argument-deduction

Semantic errors with overload resolution for init-list-as-function-argument and templates


I've configured Eclipse CDT (Eclipse v4.5.0, build id 20150621-1200; CDT v8.7.0.201506070905) for C++11 use in its continual build process, but certain expressions are still causing semantic errors even though they compile properly using g++ 4.9.2 and clang++ 3.8.0. Namely, braced init lists supplied as function arguments are not matched to the arguments' corresponding std::initializer_list constructors and the right version of LLVM's cast function is not matched to its supplied arguments either. Is Eclipse CDT using an older, internal parser that doesn't support such C++11 functionality rather than delegating to the more modern external GCC toolchain, which it does detect?

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"

using namespace llvm;

// i32 @myFunc1(i32, i32), i32 @myFunc2(i32, i32)
SmallVector<Function*, 2> getMyFuncs(Module& M) {
  Type* i32 = Type::getInt32Ty(M.getContext());

  // error #1 reported
  FunctionType* FT = FunctionType::get(i32, {i32, i32}, false); 

 // error #2 reported
  Function* F1 = cast<Function>(M.getOrInsertFunction("myFunc1", FT));

  // no error with implicit matching of ArrayRef(const std::initializer_list<T>&) here
  ArrayRef<Type*> ArgTypes = {i32, i32};
  FT = FunctionType::get(i32, ArgTypes, false);

  // error #2 reported
  Function* F2 = cast<Function>(M.getOrInsertFunction("myFunc2", FT));

   // no error with implicit matching of SmallVector(std::initializer_list<T>) here
  return {F1, F2};
}

Error #1

Invalid arguments '
Candidates are:
llvm::FunctionType * get(llvm::Type *, llvm::ArrayRef, bool)
llvm::FunctionType * get(llvm::Type *, bool)

Error #2

Invalid arguments '
Candidates are:
llvm::cast_retty<#0,#1 *>::ret_type cast(#1 *) std::enable_if::ret_type>::type cast(const #1 &)
llvm::cast_retty<#0,#1>::ret_type cast(#1 &)
'


Solution

  • Eclipse CDT uses an internal C++ code analyser called codan so that it can report what it deems to be syntax or semantic errors continuously, not just at build time. It also diagnoses what it deems to be or static analysis problems.

    When codans grasp of C++ is out of date w.r.t to your code and your compiler, then your code will compile despite codans gripes. In the Problems tab at the foot of your IDE where diagnostics appear, you can distinguish codan's gripes from those of the compiler. A compiler gripe will always be classified in the Type column as a C/C++ Problem. A codan gripe will have a type that identfies one of codan's problem categories, e.g. Semantic error, Code Analysis Problem.

    Another way to discount codan false positives is to look at the Console tab, not the Problems tab, after a build. The Console tab reports the toolchain's output.

    But when the compiler is right and codan is up-to-date and still wrong you don't want its diagnostic noise. As you would hope, you can configure codan to suppress it:-

    • Navigate Properties -> C/C++ General -> Code Analysis
    • Enable Use project settings
    • Scroll down the Problems tree-control to the category Syntax and Semantic Errors.
    • Scroll on to the subcategory Invalid Arguments (that's the complaint cited in your Error #1 and Error 2).
    • Disable this subcategory by unchecking its checkbox and OK out.

    Then Error #1 and Error 2 should go away next time the the diagnostics tab is refreshed.

    If you are unable to suppress all of codan's false diagnostics by disabling a few Syntax and Semantic Errors you can disable that entire category and just let the compiler find your compilation errors, old school.