[PATCH] D15005: Fix PR8170: Clang does not check constructor declaration that uses a template-id

2017-04-18 Thread Martell Malone via Phabricator via cfe-commits
martell added a comment.

It won't let me revert the automatically updated diff to the previous one 
because I am not the author.
@faisalv are you able todo this and Sorry for the confusion.


Repository:
  rL LLVM

https://reviews.llvm.org/D15005



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D15005: Fix PR8170: Clang does not check constructor declaration that uses a template-id

2017-04-18 Thread Martell Malone via Phabricator via cfe-commits
martell added a comment.

In case anyone comes here looking for https://reviews.llvm.org/rL300555 that 
should be https://reviews.llvm.org/D15006 no https://reviews.llvm.org/D15005.

Thanks


Repository:
  rL LLVM

https://reviews.llvm.org/D15005



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D15005: Fix PR8170: Clang does not check constructor declaration that uses a template-id

2017-04-18 Thread Martell Malone via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL300555: Driver: Better detection of mingw-gcc (authored by 
martell).

Changed prior to commit:
  https://reviews.llvm.org/D15005?vs=41206=95568#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D15005

Files:
  cfe/trunk/lib/Driver/ToolChains/MinGW.cpp
  cfe/trunk/lib/Driver/ToolChains/MinGW.h


Index: cfe/trunk/lib/Driver/ToolChains/MinGW.h
===
--- cfe/trunk/lib/Driver/ToolChains/MinGW.h
+++ cfe/trunk/lib/Driver/ToolChains/MinGW.h
@@ -93,6 +93,7 @@
   mutable std::unique_ptr Preprocessor;
   mutable std::unique_ptr Compiler;
   void findGccLibDir();
+  llvm::ErrorOr findGcc();
 };
 
 } // end namespace toolchains
Index: cfe/trunk/lib/Driver/ToolChains/MinGW.cpp
===
--- cfe/trunk/lib/Driver/ToolChains/MinGW.cpp
+++ cfe/trunk/lib/Driver/ToolChains/MinGW.cpp
@@ -285,28 +285,30 @@
   }
 }
 
+llvm::ErrorOr toolchains::MinGW::findGcc() {
+  llvm::SmallVector, 2> Gccs;
+  Gccs.emplace_back(getTriple().getArchName());
+  Gccs[0] += "-w64-mingw32-gcc";
+  Gccs.emplace_back("mingw32-gcc");
+  // Please do not add "gcc" here
+  for (StringRef CandidateGcc : Gccs)
+if (llvm::ErrorOr GPPName = 
llvm::sys::findProgramByName(CandidateGcc))
+  return GPPName;
+  return make_error_code(std::errc::no_such_file_or_directory);
+}
+
 toolchains::MinGW::MinGW(const Driver , const llvm::Triple ,
  const ArgList )
 : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
   getProgramPaths().push_back(getDriver().getInstalledDir());
 
-// In Windows there aren't any standard install locations, we search
-// for gcc on the PATH. In Linux the base is always /usr.
-#ifdef LLVM_ON_WIN32
   if (getDriver().SysRoot.size())
 Base = getDriver().SysRoot;
-  else if (llvm::ErrorOr GPPName =
-   llvm::sys::findProgramByName("gcc"))
+  else if (llvm::ErrorOr GPPName = findGcc())
 Base = llvm::sys::path::parent_path(
 llvm::sys::path::parent_path(GPPName.get()));
   else
 Base = llvm::sys::path::parent_path(getDriver().getInstalledDir());
-#else
-  if (getDriver().SysRoot.size())
-Base = getDriver().SysRoot;
-  else
-Base = "/usr";
-#endif
 
   Base += llvm::sys::path::get_separator();
   findGccLibDir();


Index: cfe/trunk/lib/Driver/ToolChains/MinGW.h
===
--- cfe/trunk/lib/Driver/ToolChains/MinGW.h
+++ cfe/trunk/lib/Driver/ToolChains/MinGW.h
@@ -93,6 +93,7 @@
   mutable std::unique_ptr Preprocessor;
   mutable std::unique_ptr Compiler;
   void findGccLibDir();
+  llvm::ErrorOr findGcc();
 };
 
 } // end namespace toolchains
Index: cfe/trunk/lib/Driver/ToolChains/MinGW.cpp
===
--- cfe/trunk/lib/Driver/ToolChains/MinGW.cpp
+++ cfe/trunk/lib/Driver/ToolChains/MinGW.cpp
@@ -285,28 +285,30 @@
   }
 }
 
+llvm::ErrorOr toolchains::MinGW::findGcc() {
+  llvm::SmallVector, 2> Gccs;
+  Gccs.emplace_back(getTriple().getArchName());
+  Gccs[0] += "-w64-mingw32-gcc";
+  Gccs.emplace_back("mingw32-gcc");
+  // Please do not add "gcc" here
+  for (StringRef CandidateGcc : Gccs)
+if (llvm::ErrorOr GPPName = llvm::sys::findProgramByName(CandidateGcc))
+  return GPPName;
+  return make_error_code(std::errc::no_such_file_or_directory);
+}
+
 toolchains::MinGW::MinGW(const Driver , const llvm::Triple ,
  const ArgList )
 : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
   getProgramPaths().push_back(getDriver().getInstalledDir());
 
-// In Windows there aren't any standard install locations, we search
-// for gcc on the PATH. In Linux the base is always /usr.
-#ifdef LLVM_ON_WIN32
   if (getDriver().SysRoot.size())
 Base = getDriver().SysRoot;
-  else if (llvm::ErrorOr GPPName =
-   llvm::sys::findProgramByName("gcc"))
+  else if (llvm::ErrorOr GPPName = findGcc())
 Base = llvm::sys::path::parent_path(
 llvm::sys::path::parent_path(GPPName.get()));
   else
 Base = llvm::sys::path::parent_path(getDriver().getInstalledDir());
-#else
-  if (getDriver().SysRoot.size())
-Base = getDriver().SysRoot;
-  else
-Base = "/usr";
-#endif
 
   Base += llvm::sys::path::get_separator();
   findGccLibDir();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D15005: Fix PR8170: Clang does not check constructor declaration that uses a template-id

2015-12-28 Thread Faisal Vali via cfe-commits
faisalv added a comment.

*ping*


http://reviews.llvm.org/D15005



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D15005: Fix PR8170: Clang does not check constructor declaration that uses a template-id

2015-12-23 Thread Faisal Vali via cfe-commits
faisalv added a comment.

*ping*


http://reviews.llvm.org/D15005



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D15005: Fix PR8170: Clang does not check constructor declaration that uses a template-id

2015-12-07 Thread David Majnemer via cfe-commits
majnemer added a subscriber: majnemer.


Comment at: lib/Sema/SemaTemplate.cpp:528
@@ +527,3 @@
+[, this](const TemplateArgument ) {
+if (const bool IsFirst = !StringifiedTemplateArgs.size())
+  StringifiedTemplateArgs = "<";

You could use `StringifiedTemplateArgs.empty()` instead.


Comment at: lib/Sema/SemaTemplate.cpp:529
@@ +528,3 @@
+if (const bool IsFirst = !StringifiedTemplateArgs.size())
+  StringifiedTemplateArgs = "<";
+else

You could hoist this bit out of the `std::for_each`


http://reviews.llvm.org/D15005



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D15005: Fix PR8170: Clang does not check constructor declaration that uses a template-id

2015-12-07 Thread Faisal Vali via cfe-commits
faisalv added inline comments.


Comment at: lib/Sema/SemaTemplate.cpp:528
@@ +527,3 @@
+[, this](const TemplateArgument ) {
+if (const bool IsFirst = !StringifiedTemplateArgs.size())
+  StringifiedTemplateArgs = "<";

majnemer wrote:
> You could use `StringifiedTemplateArgs.empty()` instead.
Aah yes - Will do - Thanks!


Comment at: lib/Sema/SemaTemplate.cpp:529
@@ +528,3 @@
+if (const bool IsFirst = !StringifiedTemplateArgs.size())
+  StringifiedTemplateArgs = "<";
+else

majnemer wrote:
> You could hoist this bit out of the `std::for_each`
Well - I would still need some way to know that this is not the first 
iteration.  I was trying to avoid declaring another variable or checking that 
the string was equal to another string (I thought the empty check would be 
reasonable) -do you feel strongly about the hoist?


http://reviews.llvm.org/D15005



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D15005: Fix PR8170: Clang does not check constructor declaration that uses a template-id

2015-11-25 Thread Faisal Vali via cfe-commits
faisalv created this revision.
faisalv added a reviewer: rsmith.
faisalv added a subscriber: cfe-commits.

Clang currently does no real checking of the template argument list when a 
template-id is used to declare a constructor:

template struct X {
  X(); // Clang erroneously accepts this.
};

Both gcc and edg emit an error on the above code (though one could claim the 
spec temp.local p1 is perhaps not as explicit as it could be in this regard)

See: https://llvm.org/bugs/show_bug.cgi?id=8170



http://reviews.llvm.org/D15005

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/Sema.h
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseExprCXX.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaTemplate.cpp
  test/CXX/temp/temp.res/temp.local/p1.cpp

Index: test/CXX/temp/temp.res/temp.local/p1.cpp
===
--- test/CXX/temp/temp.res/temp.local/p1.cpp
+++ test/CXX/temp/temp.res/temp.local/p1.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
+
 
 // C++0x [temp.local]p1:
 //   Like normal (non-template) classes, class templates have an
@@ -11,12 +11,15 @@
 template  struct X0 {
   X0();
   ~X0();
+  X0(int); 
+  X0(int*); //expected-error{{expected 'X0' or 'X0'}}
   X0 f(const X0&);
 };
 
 // Test non-type template parameters.
 template  struct X1 {
   X1();
+  template X1(char); //expected-error{{expected 'X1' or 'X1'}}
   ~X1();
   X1 f(const X1& x1a) { X1 x1b(x1a); return x1b; }
 };
Index: lib/Sema/SemaTemplate.cpp
===
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -518,6 +518,65 @@
   llvm_unreachable("Unhandled parsed template argument");
 }
 
+std::string
+Sema::stringifyTemplateArguments(const TemplateSpecializationType *TST) {
+  ArrayRef TemplateArgs(TST->getArgs(), TST->getNumArgs());
+
+  llvm::SmallString<256> StringifiedTemplateArgs;
+  std::for_each(TemplateArgs.begin(), TemplateArgs.end(),
+[, this](const TemplateArgument ) {
+if (const bool IsFirst = !StringifiedTemplateArgs.size())
+  StringifiedTemplateArgs = "<";
+else
+  StringifiedTemplateArgs += ",";
+llvm::raw_svector_ostream OS(StringifiedTemplateArgs);
+TA.print(this->getPrintingPolicy(), OS);
+  });
+
+  StringifiedTemplateArgs += ">";
+  return StringifiedTemplateArgs.c_str();
+}
+
+void Sema::checkUnqualifiedTemplateIdIsConstructor(
+TemplateIdAnnotation *TemplateId, const CXXRecordDecl *TemplatedClass) {
+  assert(TemplatedClass->getDescribedClassTemplate());
+  assert(TemplateId->Name == TemplatedClass->getIdentifier() &&
+ "TemplateId must have the same identifier as that of the class!");
+
+  // Get the type that corresponds to this template id, while suppressing all
+  // diagnostics.
+  const bool PrevSuppress = Diags.getSuppressAllDiagnostics();
+  Diags.setSuppressAllDiagnostics(true);
+  TypeResult TemplateIdTy = ActOnTemplateIdType(
+  TemplateId->SS, TemplateId->TemplateKWLoc,
+  TemplateTy::make(
+  TemplateName(TemplatedClass->getDescribedClassTemplate())),
+  TemplateId->TemplateNameLoc, TemplateId->LAngleLoc,
+  ASTTemplateArgsPtr(TemplateId->getTemplateArgs(), TemplateId->NumArgs),
+  TemplateId->RAngleLoc, /*IsCtorOrDtorName*/ true);
+  Diags.setSuppressAllDiagnostics(PrevSuppress);
+
+  // If the template-id type is the same type as the type of the
+  // templated-class, all is ok - else emit a diagnostic.
+  if (TemplateIdTy.get() &&
+  Context.hasSameType(GetTypeFromParser(TemplateIdTy.get()).getTypePtr(),
+  Context.getTypeDeclType(TemplatedClass).getTypePtr()))
+return;
+
+  // Emit a diagnostic, indicating that the template arguments do not match up
+  // to the injected class name.
+  std::string ExpectedTemplateId = TemplateId->Name->getName();
+  ExpectedTemplateId += stringifyTemplateArguments(
+  cast(Context.getTypeDeclType(TemplatedClass))
+  ->getInjectedTST());
+
+  Diag(TemplateId->TemplateNameLoc,
+   diag::err_expected_constructor_template_id)
+  << TemplateId->Name << ExpectedTemplateId.c_str()
+  << FixItHint::CreateRemoval(
+ SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc));
+}
+
 /// \brief Translates template arguments as provided by the parser
 /// into template arguments used by semantic analysis.
 void Sema::translateTemplateArguments(const ASTTemplateArgsPtr ,
Index: lib/Sema/SemaDeclCXX.cpp
===
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -1270,18 +1270,23 @@
 /// nested classes, this will only return true if II is the name of
 /// the innermost class.
 bool Sema::isCurrentClassName(const IdentifierInfo , Scope *,
-  const CXXScopeSpec *SS) {
+