r373039 - Revert r373034

2019-09-26 Thread Nicholas Allegra via cfe-commits
Author: comex
Date: Thu Sep 26 18:58:31 2019
New Revision: 373039

URL: http://llvm.org/viewvc/llvm-project?rev=373039=rev
Log:
Revert r373034

It breaks the build on MSVC.


Modified:
cfe/trunk/include/clang/AST/Stmt.h
cfe/trunk/lib/Analysis/Consumed.cpp

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=373039=373038=373039=diff
==
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Thu Sep 26 18:58:31 2019
@@ -1041,8 +1041,7 @@ protected:
   template
   struct CastIterator
   : llvm::iterator_adaptor_base, StmtPtr *,
-std::random_access_iterator_tag, TPtr,
-int, void, TPtr> {
+std::random_access_iterator_tag, TPtr> {
 using Base = typename CastIterator::iterator_adaptor_base;
 
 CastIterator() : Base(nullptr) {}

Modified: cfe/trunk/lib/Analysis/Consumed.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Consumed.cpp?rev=373039=373038=373039=diff
==
--- cfe/trunk/lib/Analysis/Consumed.cpp (original)
+++ cfe/trunk/lib/Analysis/Consumed.cpp Thu Sep 26 18:58:31 2019
@@ -494,10 +494,8 @@ public:
   void checkCallability(const PropagationInfo ,
 const FunctionDecl *FunDecl,
 SourceLocation BlameLoc);
-
-  using ArgRange = llvm::iterator_range;
-  bool handleCall(const Expr *Call, const Expr *ObjArg,
-  ArgRange args, const FunctionDecl *FunD);
+  bool handleCall(const CallExpr *Call, const Expr *ObjArg,
+  const FunctionDecl *FunD);
 
   void VisitBinaryOperator(const BinaryOperator *BinOp);
   void VisitCallExpr(const CallExpr *Call);
@@ -610,21 +608,22 @@ void ConsumedStmtVisitor::checkCallabili
 // Factors out common behavior for function, method, and operator calls.
 // Check parameters and set parameter state if necessary.
 // Returns true if the state of ObjArg is set, or false otherwise.
-bool ConsumedStmtVisitor::handleCall(const Expr *Call,
- const Expr *ObjArg,
- ArgRange Args,
+bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg,
  const FunctionDecl *FunD) {
+  unsigned Offset = 0;
+  if (isa(Call) && isa(FunD))
+Offset = 1;  // first argument is 'this'
+
   // check explicit parameters
-  unsigned Index = 0;
-  for (const Expr *Arg : Args) {
+  for (unsigned Index = Offset; Index < Call->getNumArgs(); ++Index) {
 // Skip variable argument lists.
-if (Index >= FunD->getNumParams())
+if (Index - Offset >= FunD->getNumParams())
   break;
 
-const ParmVarDecl *Param = FunD->getParamDecl(Index++);
+const ParmVarDecl *Param = FunD->getParamDecl(Index - Offset);
 QualType ParamType = Param->getType();
 
-InfoEntry Entry = findInfo(Arg);
+InfoEntry Entry = findInfo(Call->getArg(Index));
 
 if (Entry == PropagationMap.end() || Entry->second.isTest())
   continue;
@@ -637,7 +636,7 @@ bool ConsumedStmtVisitor::handleCall(con
 
   if (ParamState != ExpectedState)
 Analyzer.WarningsHandler.warnParamTypestateMismatch(
-  Arg->getExprLoc(),
+  Call->getArg(Index)->getExprLoc(),
   stateToString(ExpectedState), stateToString(ParamState));
 }
 
@@ -750,7 +749,7 @@ void ConsumedStmtVisitor::VisitCallExpr(
 return;
   }
 
-  handleCall(Call, nullptr, Call->arguments(), FunDecl);
+  handleCall(Call, nullptr, FunDecl);
   propagateReturnType(Call, FunDecl);
 }
 
@@ -806,7 +805,7 @@ void ConsumedStmtVisitor::VisitCXXMember
   if (!MD)
 return;
 
-  handleCall(Call, Call->getImplicitObjectArgument(), Call->arguments(), MD);
+  handleCall(Call, Call->getImplicitObjectArgument(), MD);
   propagateReturnType(Call, MD);
 }
 
@@ -814,20 +813,18 @@ void ConsumedStmtVisitor::VisitCXXOperat
 const CXXOperatorCallExpr *Call) {
   const auto *FunDecl = 
dyn_cast_or_null(Call->getDirectCallee());
   if (!FunDecl) return;
-  ArgRange Args = Call->arguments();
 
   if (Call->getOperator() == OO_Equal) {
-ConsumedState CS = getInfo(llvm::index(Args, 1));
-if (!handleCall(Call, llvm::index(Args, 0), llvm::drop_begin(Args, 1),
-FunDecl))
-  setInfo(llvm::index(Args, 0), CS);
+ConsumedState CS = getInfo(Call->getArg(1));
+if (!handleCall(Call, Call->getArg(0), FunDecl))
+  setInfo(Call->getArg(0), CS);
 return;
   }
 
-  if (isa(FunDecl))
-handleCall(Call, llvm::index(Args, 0), llvm::drop_begin(Args, 1), FunDecl);
+  if (const auto *MCall = dyn_cast(Call))
+handleCall(MCall, MCall->getImplicitObjectArgument(), FunDecl);
   else
-handleCall(Call, nullptr, Args, 

r373034 - [Consumed][NFC] Refactor handleCall to take function argument list.

2019-09-26 Thread Nicholas Allegra via cfe-commits
Author: comex
Date: Thu Sep 26 16:47:18 2019
New Revision: 373034

URL: http://llvm.org/viewvc/llvm-project?rev=373034=rev
Log:
[Consumed][NFC] Refactor handleCall to take function argument list.

Differential Revision: https://reviews.llvm.org/D67569


Modified:
cfe/trunk/include/clang/AST/Stmt.h
cfe/trunk/lib/Analysis/Consumed.cpp

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=373034=373033=373034=diff
==
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Thu Sep 26 16:47:18 2019
@@ -1041,7 +1041,8 @@ protected:
   template
   struct CastIterator
   : llvm::iterator_adaptor_base, StmtPtr *,
-std::random_access_iterator_tag, TPtr> {
+std::random_access_iterator_tag, TPtr,
+int, void, TPtr> {
 using Base = typename CastIterator::iterator_adaptor_base;
 
 CastIterator() : Base(nullptr) {}

Modified: cfe/trunk/lib/Analysis/Consumed.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Consumed.cpp?rev=373034=373033=373034=diff
==
--- cfe/trunk/lib/Analysis/Consumed.cpp (original)
+++ cfe/trunk/lib/Analysis/Consumed.cpp Thu Sep 26 16:47:18 2019
@@ -494,8 +494,10 @@ public:
   void checkCallability(const PropagationInfo ,
 const FunctionDecl *FunDecl,
 SourceLocation BlameLoc);
-  bool handleCall(const CallExpr *Call, const Expr *ObjArg,
-  const FunctionDecl *FunD);
+
+  using ArgRange = llvm::iterator_range;
+  bool handleCall(const Expr *Call, const Expr *ObjArg,
+  ArgRange args, const FunctionDecl *FunD);
 
   void VisitBinaryOperator(const BinaryOperator *BinOp);
   void VisitCallExpr(const CallExpr *Call);
@@ -608,22 +610,21 @@ void ConsumedStmtVisitor::checkCallabili
 // Factors out common behavior for function, method, and operator calls.
 // Check parameters and set parameter state if necessary.
 // Returns true if the state of ObjArg is set, or false otherwise.
-bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg,
+bool ConsumedStmtVisitor::handleCall(const Expr *Call,
+ const Expr *ObjArg,
+ ArgRange Args,
  const FunctionDecl *FunD) {
-  unsigned Offset = 0;
-  if (isa(Call) && isa(FunD))
-Offset = 1;  // first argument is 'this'
-
   // check explicit parameters
-  for (unsigned Index = Offset; Index < Call->getNumArgs(); ++Index) {
+  unsigned Index = 0;
+  for (const Expr *Arg : Args) {
 // Skip variable argument lists.
-if (Index - Offset >= FunD->getNumParams())
+if (Index >= FunD->getNumParams())
   break;
 
-const ParmVarDecl *Param = FunD->getParamDecl(Index - Offset);
+const ParmVarDecl *Param = FunD->getParamDecl(Index++);
 QualType ParamType = Param->getType();
 
-InfoEntry Entry = findInfo(Call->getArg(Index));
+InfoEntry Entry = findInfo(Arg);
 
 if (Entry == PropagationMap.end() || Entry->second.isTest())
   continue;
@@ -636,7 +637,7 @@ bool ConsumedStmtVisitor::handleCall(con
 
   if (ParamState != ExpectedState)
 Analyzer.WarningsHandler.warnParamTypestateMismatch(
-  Call->getArg(Index)->getExprLoc(),
+  Arg->getExprLoc(),
   stateToString(ExpectedState), stateToString(ParamState));
 }
 
@@ -749,7 +750,7 @@ void ConsumedStmtVisitor::VisitCallExpr(
 return;
   }
 
-  handleCall(Call, nullptr, FunDecl);
+  handleCall(Call, nullptr, Call->arguments(), FunDecl);
   propagateReturnType(Call, FunDecl);
 }
 
@@ -805,7 +806,7 @@ void ConsumedStmtVisitor::VisitCXXMember
   if (!MD)
 return;
 
-  handleCall(Call, Call->getImplicitObjectArgument(), MD);
+  handleCall(Call, Call->getImplicitObjectArgument(), Call->arguments(), MD);
   propagateReturnType(Call, MD);
 }
 
@@ -813,18 +814,20 @@ void ConsumedStmtVisitor::VisitCXXOperat
 const CXXOperatorCallExpr *Call) {
   const auto *FunDecl = 
dyn_cast_or_null(Call->getDirectCallee());
   if (!FunDecl) return;
+  ArgRange Args = Call->arguments();
 
   if (Call->getOperator() == OO_Equal) {
-ConsumedState CS = getInfo(Call->getArg(1));
-if (!handleCall(Call, Call->getArg(0), FunDecl))
-  setInfo(Call->getArg(0), CS);
+ConsumedState CS = getInfo(llvm::index(Args, 1));
+if (!handleCall(Call, llvm::index(Args, 0), llvm::drop_begin(Args, 1),
+FunDecl))
+  setInfo(llvm::index(Args, 0), CS);
 return;
   }
 
-  if (const auto *MCall = dyn_cast(Call))
-handleCall(MCall, MCall->getImplicitObjectArgument(), FunDecl);
+  if (isa(FunDecl))
+handleCall(Call, llvm::index(Args, 0), 

r372361 - [Consumed] Treat by-value class arguments as consuming by default, like rvalue refs.

2019-09-19 Thread Nicholas Allegra via cfe-commits
Author: comex
Date: Thu Sep 19 16:00:31 2019
New Revision: 372361

URL: http://llvm.org/viewvc/llvm-project?rev=372361=rev
Log:
[Consumed] Treat by-value class arguments as consuming by default, like rvalue 
refs.

Differential Revision: https://reviews.llvm.org/D67743

Modified:
cfe/trunk/lib/Analysis/Consumed.cpp
cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp

Modified: cfe/trunk/lib/Analysis/Consumed.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Consumed.cpp?rev=372361=372360=372361=diff
==
--- cfe/trunk/lib/Analysis/Consumed.cpp (original)
+++ cfe/trunk/lib/Analysis/Consumed.cpp Thu Sep 19 16:00:31 2019
@@ -644,10 +644,10 @@ bool ConsumedStmtVisitor::handleCall(con
   continue;
 
 // Adjust state on the caller side.
-if (isRValueRef(ParamType))
-  setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Consumed);
-else if (ReturnTypestateAttr *RT = Param->getAttr())
+if (ReturnTypestateAttr *RT = Param->getAttr())
   setStateForVarOrTmp(StateMap, PInfo, mapReturnTypestateAttrState(RT));
+else if (isRValueRef(ParamType) || isConsumableType(ParamType))
+  setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Consumed);
 else if (isPointerOrRef(ParamType) &&
  (!ParamType->getPointeeType().isConstQualified() ||
   isSetOnReadPtrType(ParamType)))

Modified: cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp?rev=372361=372360=372361=diff
==
--- cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-consumed-analysis.cpp Thu Sep 19 16:00:31 2019
@@ -53,12 +53,18 @@ class CONSUMABLE(unconsumed) DestructorT
 public:
   DestructorTester();
   DestructorTester(int);
+  DestructorTester(nullptr_t) RETURN_TYPESTATE(unconsumed);
+  DestructorTester(DestructorTester &&);
   
   void operator*() CALLABLE_WHEN("unconsumed");
   
   ~DestructorTester() CALLABLE_WHEN("consumed");
+
 };
 
+void dtByVal(DestructorTester);
+void dtByValMarkUnconsumed(DestructorTester RETURN_TYPESTATE(unconsumed));
+
 void baf0(const ConsumableClass  var);
 void baf1(const ConsumableClass );
 void baf2(const ConsumableClass *var);
@@ -120,6 +126,19 @@ void testDestruction() {
  expected-warning {{invalid invocation of method 
'~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}}
 }
 
+void testDestructionByVal() {
+  {
+// both the var and the temporary are consumed:
+DestructorTester D0(nullptr);
+dtByVal((DestructorTester &&)D0);
+  }
+  {
+// the var is consumed but the temporary isn't:
+DestructorTester D1(nullptr);
+dtByValMarkUnconsumed((DestructorTester &&)D1); // expected-warning 
{{invalid invocation of method '~DestructorTester' on a temporary object while 
it is in the 'unconsumed' state}}
+  }
+}
+
 void testTempValue() {
   *ConsumableClass(); // expected-warning {{invalid invocation of method 
'operator*' on a temporary object while it is in the 'consumed' state}}
 }
@@ -413,10 +432,15 @@ void testParamReturnTypestateCallee(bool
   Param.consume();
 }
 
+void testRvalueRefParamReturnTypestateCallee(ConsumableClass & 
RETURN_TYPESTATE(unconsumed)) {
+  Param.unconsume();
+}
+
 void testParamReturnTypestateCaller() {
   ConsumableClass var;
   
   testParamReturnTypestateCallee(true, var);
+  testRvalueRefParamReturnTypestateCallee((ConsumableClass &&)var);
   
   *var;
 }
@@ -480,6 +504,9 @@ void testCallingConventions() {
   
   baf2();  
   *var;
+
+  baf3(var);
+  *var;
   
   baf4(var);  
   *var; // expected-warning {{invalid invocation of method 'operator*' on 
object 'var' while it is in the 'unknown' state}}


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


r372058 - Push lambda scope earlier when transforming lambda expression

2019-09-16 Thread Nicholas Allegra via cfe-commits
Author: comex
Date: Mon Sep 16 18:43:33 2019
New Revision: 372058

URL: http://llvm.org/viewvc/llvm-project?rev=372058=rev
Log:
Push lambda scope earlier when transforming lambda expression

Differential Revision: https://reviews.llvm.org/D66067


Modified:
cfe/trunk/lib/Sema/TreeTransform.h
cfe/trunk/test/SemaTemplate/default-arguments-cxx0x.cpp

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=372058=372057=372058=diff
==
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Mon Sep 16 18:43:33 2019
@@ -11325,10 +11325,14 @@ TreeTransform::TransformLambdaE
 }
   }
 
+  LambdaScopeInfo *LSI = getSema().PushLambdaScope();
+  Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
+
   // Transform the template parameters, and add them to the current
   // instantiation scope. The null case is handled correctly.
   auto TPL = getDerived().TransformTemplateParameterList(
   E->getTemplateParameterList());
+  LSI->GLTemplateParameterList = TPL;
 
   // Transform the type of the original lambda's call operator.
   // The transformation MUST be done in the CurrentInstantiationScope since
@@ -11355,10 +11359,6 @@ TreeTransform::TransformLambdaE
 NewCallOpType);
   }
 
-  LambdaScopeInfo *LSI = getSema().PushLambdaScope();
-  Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
-  LSI->GLTemplateParameterList = TPL;
-
   // Create the local class that will describe the lambda.
   CXXRecordDecl *OldClass = E->getLambdaClass();
   CXXRecordDecl *Class

Modified: cfe/trunk/test/SemaTemplate/default-arguments-cxx0x.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/default-arguments-cxx0x.cpp?rev=372058=372057=372058=diff
==
--- cfe/trunk/test/SemaTemplate/default-arguments-cxx0x.cpp (original)
+++ cfe/trunk/test/SemaTemplate/default-arguments-cxx0x.cpp Mon Sep 16 18:43:33 
2019
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s
 // expected-no-diagnostics
 
 // Test default template arguments for function templates.
@@ -114,3 +115,17 @@ namespace rdar34167492 {
 S _a{};
   };
 }
+
+#if __cplusplus >= 201402L
+namespace lambda {
+  // Verify that a default argument in a lambda can refer to the type of a
+  // previous `auto` argument without crashing.
+  template 
+  void bar() {
+(void) [](auto c, int x = sizeof(decltype(c))) {};
+  }
+  void foo() {
+bar();
+  }
+} // namespace lambda
+#endif


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


Re: [PATCH] D15907: Allow various function attributes to be specified on Objective-C blocks too.

2016-01-13 Thread Nicholas Allegra via cfe-commits
comex added reviewers: aaron.ballman, rsmith.
comex added a comment.

Ping, and adding potential reviewers like I was supposed to do in the first 
place.


http://reviews.llvm.org/D15907



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


[PATCH] D15907: Allow various function attributes to be specified on Objective-C blocks too.

2016-01-05 Thread Nicholas Allegra via cfe-commits
comex created this revision.
comex added a subscriber: cfe-commits.
Herald added a subscriber: aemerson.

This mostly "just works" by adding Block to the subject list, but there is an
issue with warnings in attribute handlers tied to the return type, which for
blocks can be inferred.  My solution to this is a bit ugly but seems to do the
right thing.

The list: always_inline, noinline, cold, hot, minsize, malloc,
disable_tail_calls, noalias, noduplicate, nonnull, returns_nonnull, optnone.

nonnull already partially worked on blocks, but fix applying it to parameters
on them; also, improve the error message and add additional tests.

Most of these attributes only make sense when the target of a function call is
known; since blocks are always called indirectly via pointers, these will only
work if the optimizer is able to replace the indirect calls with direct calls
(ergo not at all at -O0).  However, this can still be useful in practice.

For now, all of them only apply to the block implementation function itself, as
opposed to the copy and dispose helpers.  For those it might make sense to
propagate always_inline in particular, or perhaps to just add some explicit
syntax for putting attributes on them, but it's not essential.

Incidentally, for some of these attributes and some not included, such as
returns_nonnull, printf, warn_unused_result, etc., it would be somewhat useful
and more principled to allow them as part of function types rather than just
functions themselves, for the sake of both standard function pointer calls and
blocks.  Currently only a handful of attributes can be used on types: noreturn,
ns_returns_retained, regparm, and calling convention.  However, that would be a
larger change and orthogonal to this patch.


http://reviews.llvm.org/D15907

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/AttributeList.h
  include/clang/Sema/Sema.h
  lib/Parse/ParseExpr.cpp
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/TreeTransform.h
  test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp
  test/CodeGen/always-inline.c
  test/CodeGen/attr-disable-tail-calls.c
  test/CodeGen/attr-noinline.c
  test/CodeGen/attr-optnone.c
  test/CodeGen/nonnull.c
  test/Parser/cxx0x-attributes.cpp
  test/Sema/attr-capabilities.c
  test/Sema/attr-coldhot.c
  test/Sema/attr-disable-tail-calls.c
  test/Sema/attr-malloc.c
  test/Sema/attr-minsize.c
  test/Sema/attr-noinline.c
  test/Sema/nonnull.c
  test/SemaObjC/attr-cf_returns.m
  test/SemaObjC/objcbridge-attribute-arc.m
  test/SemaObjC/objcbridge-attribute.m
  utils/TableGen/ClangAttrEmitter.cpp

Index: utils/TableGen/ClangAttrEmitter.cpp
===
--- utils/TableGen/ClangAttrEmitter.cpp
+++ utils/TableGen/ClangAttrEmitter.cpp
@@ -2363,10 +2363,12 @@
 case GenericRecord:
   return "(S.getLangOpts().CPlusPlus ? ExpectedStructOrUnionOrClass : "
"ExpectedStructOrUnion)";
+case Func | Block: return "ExpectedFunctionOrBlock";
 case Func | ObjCMethod | Block: return "ExpectedFunctionMethodOrBlock";
 case Func | ObjCMethod | Class: return "ExpectedFunctionMethodOrClass";
 case Func | Param:
 case Func | ObjCMethod | Param: return "ExpectedFunctionMethodOrParameter";
+case Func | ObjCMethod | Block | Param: return "ExpectedFunctionMethodBlockOrParameter";
 case Func | ObjCMethod: return "ExpectedFunctionOrMethod";
 case Func | Var: return "ExpectedVariableOrFunction";
 
Index: test/SemaObjC/objcbridge-attribute.m
===
--- test/SemaObjC/objcbridge-attribute.m
+++ test/SemaObjC/objcbridge-attribute.m
@@ -38,7 +38,7 @@
 
 @interface I
 {
-   __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to structs, unions, and typedefs}};
+   __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to structs, unions and typedefs}};
 }
 @end
 
Index: test/SemaObjC/objcbridge-attribute-arc.m
===
--- test/SemaObjC/objcbridge-attribute-arc.m
+++ test/SemaObjC/objcbridge-attribute-arc.m
@@ -32,7 +32,7 @@
 
 @interface I
 {
-   __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to structs, unions, and typedefs}};
+   __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to structs, unions and typedefs}};
 }
 @end
 
Index: test/SemaObjC/attr-cf_returns.m
===
--- test/SemaObjC/attr-cf_returns.m
+++ test/SemaObjC/attr-cf_returns.m
@@ -10,8 +10,8 @@
 #define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
 #define CF_RETURNS_NOT_RETAINED 

[PATCH] D15406: Add warning for attribute-cleanup on function parameter.

2015-12-09 Thread Nicholas Allegra via cfe-commits
comex created this revision.
comex added a subscriber: cfe-commits.

When a function parameter is declared `__attribute__((cleanup))`, neither Clang 
nor GCC actually executes the cleanup function, but Clang didn't warn about it. 
 For the sake of compatibility, add a warning rather than making the attribute 
actually work.

http://reviews.llvm.org/D15406

Files:
  lib/Sema/SemaDeclAttr.cpp
  test/Sema/attr-cleanup.c

Index: test/Sema/attr-cleanup.c
===
--- test/Sema/attr-cleanup.c
+++ test/Sema/attr-cleanup.c
@@ -46,3 +46,5 @@
 void t6(void) {
   int i __attribute__((cleanup((void *)0)));  // expected-error {{'cleanup' 
argument is not a function}}
 }
+
+void t7(__attribute__((cleanup(c4))) int a) {} // expected-warning {{'cleanup' 
attribute ignored}}
Index: lib/Sema/SemaDeclAttr.cpp
===
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -2595,7 +2595,7 @@
 
 static void handleCleanupAttr(Sema , Decl *D, const AttributeList ) {
   VarDecl *VD = cast(D);
-  if (!VD->hasLocalStorage()) {
+  if (!VD->hasLocalStorage() || isa(VD)) {
 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
 return;
   }


Index: test/Sema/attr-cleanup.c
===
--- test/Sema/attr-cleanup.c
+++ test/Sema/attr-cleanup.c
@@ -46,3 +46,5 @@
 void t6(void) {
   int i __attribute__((cleanup((void *)0)));  // expected-error {{'cleanup' argument is not a function}}
 }
+
+void t7(__attribute__((cleanup(c4))) int a) {} // expected-warning {{'cleanup' attribute ignored}}
Index: lib/Sema/SemaDeclAttr.cpp
===
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -2595,7 +2595,7 @@
 
 static void handleCleanupAttr(Sema , Decl *D, const AttributeList ) {
   VarDecl *VD = cast(D);
-  if (!VD->hasLocalStorage()) {
+  if (!VD->hasLocalStorage() || isa(VD)) {
 S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
 return;
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D12686: Add support for GCC's '__auto_type' extension.

2015-11-10 Thread Nicholas Allegra via cfe-commits
comex updated this revision to Diff 39838.
comex marked 16 inline comments as done.

http://reviews.llvm.org/D12686

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/Type.h
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/Type.cpp
  lib/AST/TypePrinter.cpp
  lib/Format/TokenAnnotator.cpp
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseObjc.cpp
  lib/Parse/ParseTentative.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTWriter.cpp
  test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
  test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7-1y.cpp
  test/Sema/auto-type.c
  test/Sema/bitfield.c
  test/Sema/exprs.c
  test/SemaCXX/auto-type-from-cxx.cpp
  test/SemaCXX/cxx98-compat.cpp

Index: test/SemaCXX/cxx98-compat.cpp
===
--- test/SemaCXX/cxx98-compat.cpp
+++ test/SemaCXX/cxx98-compat.cpp
@@ -100,6 +100,9 @@
 };
 
 auto f() -> int; // expected-warning {{trailing return types are incompatible with C++98}}
+#ifdef CXX14COMPAT
+auto ff() { return 5; } // expected-warning {{'auto' type specifier is incompatible with C++98}}
+#endif
 
 void RangeFor() {
   int xs[] = {1, 2, 3};
Index: test/SemaCXX/auto-type-from-cxx.cpp
===
--- /dev/null
+++ test/SemaCXX/auto-type-from-cxx.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
+
+struct A {
+operator __auto_type() {} // expected-error {{'__auto_type' not allowed in conversion function type}}
+};
+
+__auto_type a() -> int; // expected-error {{'__auto_type' not allowed in function return type}}
+template 
+__auto_type b() { return T::x; } // expected-error {{'__auto_type' not allowed in function return type}}
+auto c() -> __auto_type { __builtin_unreachable(); } // expected-error {{'__auto_type' not allowed in function return type}}
+int d() {
+  decltype(__auto_type) e = 1; // expected-error {{expected expression}}
+  auto _ = [](__auto_type f) {}; // expected-error {{'__auto_type' not allowed in lambda parameter}}
+  __auto_type g = 2;
+  struct BitField { int field:2; };
+  __auto_type h = BitField{1}.field; // (should work from C++)
+  new __auto_type; // expected-error {{'__auto_type' not allowed in type allocated by 'new'}}
+}
+
Index: test/Sema/exprs.c
===
--- test/Sema/exprs.c
+++ test/Sema/exprs.c
@@ -97,6 +97,7 @@
   R = __alignof(P->x);  // expected-error {{invalid application of 'alignof' to bit-field}}
   R = __alignof(P->y);   // ok.
   R = sizeof(P->x); // expected-error {{invalid application of 'sizeof' to bit-field}}
+  __extension__ ({ R = (__typeof__(P->x)) 2; }); // expected-error {{invalid application of 'typeof' to bit-field}}
   return R;
 }
 
Index: test/Sema/bitfield.c
===
--- test/Sema/bitfield.c
+++ test/Sema/bitfield.c
@@ -63,7 +63,8 @@
 typedef signed Signed;
 
 struct Test5 { unsigned n : 2; } t5;
-typedef __typeof__(t5.n) Unsigned; // Bitfield is unsigned
+// Bitfield is unsigned
+struct Test5 sometest5 = {-1}; // expected-warning {{implicit truncation from 'int' to bitfield changes value from -1 to 3}}
 typedef __typeof__(+t5.n) Signed;  // ... but promotes to signed.
 
 typedef __typeof__(t5.n + 0) Signed; // Arithmetic promotes.
Index: test/Sema/auto-type.c
===
--- /dev/null
+++ test/Sema/auto-type.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic -std=c11
+
+__auto_type a = 5; // expected-warning {{'__auto_type' is a GNU extension}}
+__extension__ __auto_type a1 = 5;
+#pragma clang diagnostic ignored "-Wgnu-auto-type"
+__auto_type b = 5.0;
+__auto_type c = 
+__auto_type d = (struct {int a;}) {5};
+_Static_assert(__builtin_types_compatible_p(__typeof(a), int), "");
+__auto_type e = e; // expected-error {{variable 'e' declared with '__auto_type' type cannot appear in its own initializer}}
+
+struct s { __auto_type a; }; // expected-error {{'__auto_type' not allowed in struct member}}
+
+__auto_type f = 1, g = 1.0; // expected-error {{'__auto_type' deduced as 'int' in declaration of 'f' and deduced as 'double' in declaration of 'g'}}
+
+__auto_type h() {} // expected-error {{'__auto_type' not allowed in function return type}}
+
+int i() {
+  struct bitfield { int field:2; };
+  __auto_type j = (struct bitfield){1}.field; // expected-error {{cannot pass 

Re: [PATCH] D12686: Add support for GCC's '__auto_type' extension.

2015-11-10 Thread Nicholas Allegra via cfe-commits
comex added a comment.

Addressed comments.  Thanks, rsmith!



Comment at: lib/Sema/SemaType.cpp:3756-3760
@@ -3743,2 +3755,7 @@
   }
+} else if (D.getDeclSpec().getTypeSpecType() == 
DeclSpec::TST_auto_type) {
+  S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
+ diag::err_auto_not_allowed)
+<< 2 << 13 << D.getDeclSpec().getSourceRange();
+  D.setInvalidType(true);
 }

rsmith wrote:
> Please deal with this in the "checking for auto" block at the top rather than 
> repeating the diagnostic code here with magic numbers; maybe change
> 
>   (!SemaRef.getLangOpts().CPlusPlus11 || !D.isFunctionDeclarator())) {
> 
> to
> 
>   (!SemaRef.getLangOpts().CPlusPlus11 || !D.isFunctionDeclarator() || 
> D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto_type)) {
> 
> up there.
For the sake of clarity, I removed that whole bit from the if condition instead 
and moved the C++11 test down to where it sets `Error`.  Two bits of fallout 
from this:
- `typedef decltype(auto) f();` gets diagnosed there rather than later with a 
different error; I updated the test, since both errors seem reasonable.
- A bug is fixed where definitions like `auto f() { return 5; }` were not being 
caught with `-std=c++14 -Wc++98-compat`.  I updated the c++98-compat test to 
add this case.


http://reviews.llvm.org/D12686



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


Re: [PATCH] D12686: Add support for GCC's '__auto_type' extension.

2015-11-05 Thread Nicholas Allegra via cfe-commits
comex added a comment.

(Ping?  I verified yesterday that the patch still applies and passes regression 
tests.)


http://reviews.llvm.org/D12686



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


Re: [PATCH] D12686: Add support for GCC's '__auto_type' extension.

2015-10-21 Thread Nicholas Allegra via cfe-commits
comex added a comment.

One more ping.  As far as I know, everything has been addressed.


http://reviews.llvm.org/D12686



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


Re: [PATCH] D12686: Add support for GCC's '__auto_type' extension.

2015-10-13 Thread Nicholas Allegra via cfe-commits
comex added inline comments.


Comment at: lib/Sema/SemaType.cpp:2654-2655
@@ -2648,4 +2653,4 @@
 case Declarator::ConversionIdContext:
   if (!SemaRef.getLangOpts().CPlusPlus14)
-Error = 12; // conversion-type-id
+Error = 14; // conversion-type-id
   break;

rsmith wrote:
> Do you really want to allow `__auto_type` here? This is inconsistent with 
> what you do for return types.
Also a mistake.


Comment at: test/SemaCXX/auto-type-from-cxx.cpp:14
@@ +13,3 @@
+  auto _ = [](__auto_type f) {}; // expected-error {{'__auto_type' not allowed 
in lambda parameter}}
+  __auto_type g = 2;
+  struct BitField { int field:2; };

thakis wrote:
> Shouldn't this say "warning: __auto_type is a gnu extension" (since this uses 
> -std=c++14, not -std=gnu++14)?
Hmm... when I added `ext_auto_type` to the .td, I didn't notice the difference 
between Extension and ExtWarn.  Since the patch currently uses Extension, it 
won't warn by default, but will with `-pedantic`, `-Wgnu`, or 
`-Wgnu-auto-type`.  The C test uses `-pedantic` so it gets the warning.

Is there an explicit policy on which extensions should be ExtWarn?  Looking at 
the rest of that file, ExtWarns seem to be mostly either (a) standardized 
extensions (which will warn if `-std` is too early) and (b) 'extensions' that 
are more like "Clang will accept your buggy code" than features.  Most GNU 
extensions are just Extension, so I think it makes sense to do the same for 
`__auto_type`.

I could update the C++ test to add `-pedantic`, but arguably it makes more 
sense to test the fact that the warning is not emitted by default.


http://reviews.llvm.org/D12686



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


Re: [PATCH] D12686: Add support for GCC's '__auto_type' extension.

2015-10-13 Thread Nicholas Allegra via cfe-commits
comex added inline comments.


Comment at: lib/Sema/SemaType.cpp:2675-2678
@@ -2671,5 +2674,6 @@
   break;
 case Declarator::ConversionIdContext:
-  if (!SemaRef.getLangOpts().CPlusPlus14)
-Error = 12; // conversion-type-id
+  if (!SemaRef.getLangOpts().CPlusPlus14 ||
+  D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto_type)
+Error = 14; // conversion-type-id
   break;

(Clarification: The "also a mistake" comment was meant to be submitted earlier, 
but was left in the Phabricator draft state; I already fixed this.)


http://reviews.llvm.org/D12686



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


Re: [PATCH] D12686: Add support for GCC's '__auto_type' extension.

2015-10-13 Thread Nicholas Allegra via cfe-commits
comex added inline comments.


Comment at: test/SemaCXX/auto-type-from-cxx.cpp:14
@@ +13,3 @@
+  auto _ = [](__auto_type f) {}; // expected-error {{'__auto_type' not allowed 
in lambda parameter}}
+  __auto_type g = 2;
+  struct BitField { int field:2; };

thakis wrote:
> comex wrote:
> > thakis wrote:
> > > Shouldn't this say "warning: __auto_type is a gnu extension" (since this 
> > > uses -std=c++14, not -std=gnu++14)?
> > Hmm... when I added `ext_auto_type` to the .td, I didn't notice the 
> > difference between Extension and ExtWarn.  Since the patch currently uses 
> > Extension, it won't warn by default, but will with `-pedantic`, `-Wgnu`, or 
> > `-Wgnu-auto-type`.  The C test uses `-pedantic` so it gets the warning.
> > 
> > Is there an explicit policy on which extensions should be ExtWarn?  Looking 
> > at the rest of that file, ExtWarns seem to be mostly either (a) 
> > standardized extensions (which will warn if `-std` is too early) and (b) 
> > 'extensions' that are more like "Clang will accept your buggy code" than 
> > features.  Most GNU extensions are just Extension, so I think it makes 
> > sense to do the same for `__auto_type`.
> > 
> > I could update the C++ test to add `-pedantic`, but arguably it makes more 
> > sense to test the fact that the warning is not emitted by default.
> I'm not sure either. `typeof` warns with -std=c++14 but not with 
> -std=gnu++14. From a user perspective, this makes sense to me: I want to 
> write standard c++ and I want the compiler to help me with that, but I don't 
> want to get all the pedantic warnings that -pedantic entails. For example, 
> consider using clang-cl to build Windows code, and wanting MSVC to be able to 
> build said Windows code too. (This can of course go wrong with standard C++ 
> too, but in that case I'm running into MSVC bugs which will eventually be 
> fixed.) So if it's possible to match how typeof works, I think that'd be 
> good. If it's not possible, this wouldn't be the only GNU extension allowed 
> in -std=c++14 mode though, so it's not a big thing.
As far as I can tell, `typeof` doesn't warn at all.  In standard mode it's an 
*error* because `typeof` is treated as a normal identifier (so that code that 
uses it as such doesn't break), but if you use the reserved-namespace keyword 
`__typeof`, there is no warning even with `-Weverything`.


http://reviews.llvm.org/D12686



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


Re: [PATCH] D12686: Add support for GCC's '__auto_type' extension.

2015-10-12 Thread Nicholas Allegra via cfe-commits
comex added a comment.

Ping again.


http://reviews.llvm.org/D12686



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


Re: [PATCH] D12686: Add support for GCC's '__auto_type' extension.

2015-10-12 Thread Nicholas Allegra via cfe-commits
comex updated the summary for this revision.
comex updated this revision to Diff 37202.
comex marked 3 inline comments as done.
comex added a comment.

Fixed raised issues.

(I don't have commit rights.)


http://reviews.llvm.org/D12686

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/Type.h
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/Type.cpp
  lib/AST/TypePrinter.cpp
  lib/Format/TokenAnnotator.cpp
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseObjc.cpp
  lib/Parse/ParseTentative.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTWriter.cpp
  test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
  test/Sema/auto-type.c
  test/Sema/bitfield.c
  test/Sema/exprs.c
  test/SemaCXX/auto-type-from-cxx.cpp

Index: test/SemaCXX/auto-type-from-cxx.cpp
===
--- /dev/null
+++ test/SemaCXX/auto-type-from-cxx.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
+
+struct A {
+operator __auto_type() {} // expected-error {{'__auto_type' not allowed in conversion function type}}
+};
+
+__auto_type a() -> int; // expected-error {{function with trailing return type must specify return type 'auto', not '__auto_type'}}
+template 
+__auto_type b() { return T::x; } // expected-error {{'__auto_type' not allowed in function return type}}
+auto c() -> __auto_type { __builtin_unreachable(); } // expected-error {{'__auto_type' not allowed in function return type}}
+int d() {
+  decltype(__auto_type) e = 1; // expected-error {{expected expression}}
+  auto _ = [](__auto_type f) {}; // expected-error {{'__auto_type' not allowed in lambda parameter}}
+  __auto_type g = 2;
+  struct BitField { int field:2; };
+  __auto_type h = BitField{1}.field; // (should work from C++)
+  new __auto_type; // expected-error {{cannot use '__auto_type' as 'new' type}}
+}
+
Index: test/Sema/exprs.c
===
--- test/Sema/exprs.c
+++ test/Sema/exprs.c
@@ -97,6 +97,7 @@
   R = __alignof(P->x);  // expected-error {{invalid application of 'alignof' to bit-field}}
   R = __alignof(P->y);   // ok.
   R = sizeof(P->x); // expected-error {{invalid application of 'sizeof' to bit-field}}
+  __extension__ ({ R = (__typeof__(P->x)) 2; }); // expected-error {{invalid application of 'typeof' to bit-field}}
   return R;
 }
 
Index: test/Sema/bitfield.c
===
--- test/Sema/bitfield.c
+++ test/Sema/bitfield.c
@@ -63,7 +63,8 @@
 typedef signed Signed;
 
 struct Test5 { unsigned n : 2; } t5;
-typedef __typeof__(t5.n) Unsigned; // Bitfield is unsigned
+// Bitfield is unsigned
+struct Test5 sometest5 = {-1}; // expected-warning {{implicit truncation from 'int' to bitfield changes value from -1 to 3}}
 typedef __typeof__(+t5.n) Signed;  // ... but promotes to signed.
 
 typedef __typeof__(t5.n + 0) Signed; // Arithmetic promotes.
Index: test/Sema/auto-type.c
===
--- /dev/null
+++ test/Sema/auto-type.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic -std=c11
+
+__auto_type a = 5; // expected-warning {{'__auto_type' is a GNU extension}}
+__extension__ __auto_type a1 = 5;
+#pragma clang diagnostic ignored "-Wgnu-auto-type"
+__auto_type b = 5.0;
+__auto_type c = 
+__auto_type d = (struct {int a;}) {5};
+_Static_assert(__builtin_types_compatible_p(__typeof(a), int), "");
+__auto_type e = e; // expected-error {{variable 'e' declared with '__auto_type' type cannot appear in its own initializer}}
+
+struct s { __auto_type a; }; // expected-error {{'__auto_type' not allowed in struct member}}
+
+__auto_type f = 1, g = 1.0; // expected-error {{'__auto_type' deduced as 'int' in declaration of 'f' and deduced as 'double' in declaration of 'g'}}
+
+__auto_type h() {} // expected-error {{'__auto_type' not allowed in function return type}}
+
+int i() {
+  struct bitfield { int field:2; };
+  __auto_type j = (struct bitfield){1}.field; // expected-error {{cannot pass bit-field as __auto_type initializer in C}}
+
+}
Index: test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
===
--- test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
+++ test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
@@ -3,9 +3,9 @@
 
 // FIXME: This is in p11 (?) in C++1y.
 void f() {
-  

Re: [PATCH] D12686: Add support for GCC's '__auto_type' extension.

2015-10-12 Thread Nicholas Allegra via cfe-commits
comex marked 5 inline comments as done.


Comment at: include/clang/Basic/DiagnosticSemaKinds.td:1726
@@ -1720,1 +1725,3 @@
+def err_auto_bitfield : Error<
+  "cannot pass bit-field as __auto_type initializer in C">;
 

rsmith wrote:
> pass -> use
> 
> Also, why not? Just because GCC messes this up, doesn't mean we have to.
By analogy with the standards-defined inability to use sizeof on bit fields, it 
made sense to me to do what GCC does and forbid getting their type in other 
ways.  Though I suppose the restriction is somewhat questionable in the first 
place.


Comment at: lib/AST/ItaniumMangle.cpp:2557-2558
@@ -2557,1 +2556,4 @@
+  if (D.isNull()) {
+assert(T->getKeyword() != AutoTypeKeyword::GNUAutoType &&
+   "shouldn't need to mangle __auto_type!");
 Out << (T->isDecltypeAuto() ? "Dc" : "Da");

rsmith wrote:
> Why not?
> 
>   template void f(decltype(new __auto_type(T(;
> 
> ... would need a mangling, right? (Or do you prohibit `__auto_type` there?)
Since my goal is to only allow `__auto_type` in C-compatible contexts, this 
should be prohibited, but wasn't.  Fixed.  (Any other cases I haven't thought 
of?)


Comment at: lib/Parse/ParseDeclCXX.cpp:1119
@@ -1118,2 +1118,3 @@
   case tok::kw_auto:// struct foo {...} auto  x;
+  case tok::kw___auto_type: // struct foo {...} __auto_type x;
   case tok::kw_mutable: // struct foo {...} mutable   x;

rsmith wrote:
> That would be ill-formed; revert this change.
Fixed.  Durr.


Comment at: lib/Sema/SemaType.cpp:1457
@@ -1455,3 +1456,3 @@
 // being analyzed (which tracks the invented type template parameter).
 if (declarator.getContext() == Declarator::LambdaExprParameterContext) {
   sema::LambdaScopeInfo *LSI = S.getCurLambda();

rsmith wrote:
> Should we really allow using `__auto_type` to introduce a generic lambda? It 
> seems like there's a major open design question here: either we should allow 
> `__auto_type` only in GCC-compatible contexts (that is, as a decl-specifier 
> that's not a function return type), or we should allow it everywhere we allow 
> `auto` and make it a synonym for `auto` in C++ (in which case it needs to be 
> mangled, and the distinction between `auto` and `__auto_type` should probably 
> not affect the canonical type).
My goal was to do the former; if you'd prefer to just make it a synonym.  In 
this case, the patch prevents `__auto_type` from being used in lambda 
parameters elsewhere.


http://reviews.llvm.org/D12686



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


Re: [PATCH] D12686: Add support for GCC's '__auto_type' extension.

2015-10-12 Thread Nicholas Allegra via cfe-commits
comex updated this revision to Diff 37215.
comex added a comment.

Okay.


http://reviews.llvm.org/D12686

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/Type.h
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/Type.cpp
  lib/AST/TypePrinter.cpp
  lib/Format/TokenAnnotator.cpp
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseObjc.cpp
  lib/Parse/ParseTentative.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTWriter.cpp
  test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
  test/Sema/auto-type.c
  test/Sema/bitfield.c
  test/Sema/exprs.c
  test/SemaCXX/auto-type-from-cxx.cpp

Index: test/SemaCXX/auto-type-from-cxx.cpp
===
--- /dev/null
+++ test/SemaCXX/auto-type-from-cxx.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
+
+struct A {
+operator __auto_type() {} // expected-error {{'__auto_type' not allowed in conversion function type}}
+};
+
+__auto_type a() -> int; // expected-error {{function with trailing return type must specify return type 'auto', not '__auto_type'}}
+template 
+__auto_type b() { return T::x; } // expected-error {{'__auto_type' not allowed in function return type}}
+auto c() -> __auto_type { __builtin_unreachable(); } // expected-error {{'__auto_type' not allowed in function return type}}
+int d() {
+  decltype(__auto_type) e = 1; // expected-error {{expected expression}}
+  auto _ = [](__auto_type f) {}; // expected-error {{'__auto_type' not allowed in lambda parameter}}
+  __auto_type g = 2;
+  struct BitField { int field:2; };
+  __auto_type h = BitField{1}.field; // (should work from C++)
+  new __auto_type; // expected-error {{'__auto_type' not allowed in 'new' argument}}
+}
+
Index: test/Sema/exprs.c
===
--- test/Sema/exprs.c
+++ test/Sema/exprs.c
@@ -97,6 +97,7 @@
   R = __alignof(P->x);  // expected-error {{invalid application of 'alignof' to bit-field}}
   R = __alignof(P->y);   // ok.
   R = sizeof(P->x); // expected-error {{invalid application of 'sizeof' to bit-field}}
+  __extension__ ({ R = (__typeof__(P->x)) 2; }); // expected-error {{invalid application of 'typeof' to bit-field}}
   return R;
 }
 
Index: test/Sema/bitfield.c
===
--- test/Sema/bitfield.c
+++ test/Sema/bitfield.c
@@ -63,7 +63,8 @@
 typedef signed Signed;
 
 struct Test5 { unsigned n : 2; } t5;
-typedef __typeof__(t5.n) Unsigned; // Bitfield is unsigned
+// Bitfield is unsigned
+struct Test5 sometest5 = {-1}; // expected-warning {{implicit truncation from 'int' to bitfield changes value from -1 to 3}}
 typedef __typeof__(+t5.n) Signed;  // ... but promotes to signed.
 
 typedef __typeof__(t5.n + 0) Signed; // Arithmetic promotes.
Index: test/Sema/auto-type.c
===
--- /dev/null
+++ test/Sema/auto-type.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic -std=c11
+
+__auto_type a = 5; // expected-warning {{'__auto_type' is a GNU extension}}
+__extension__ __auto_type a1 = 5;
+#pragma clang diagnostic ignored "-Wgnu-auto-type"
+__auto_type b = 5.0;
+__auto_type c = 
+__auto_type d = (struct {int a;}) {5};
+_Static_assert(__builtin_types_compatible_p(__typeof(a), int), "");
+__auto_type e = e; // expected-error {{variable 'e' declared with '__auto_type' type cannot appear in its own initializer}}
+
+struct s { __auto_type a; }; // expected-error {{'__auto_type' not allowed in struct member}}
+
+__auto_type f = 1, g = 1.0; // expected-error {{'__auto_type' deduced as 'int' in declaration of 'f' and deduced as 'double' in declaration of 'g'}}
+
+__auto_type h() {} // expected-error {{'__auto_type' not allowed in function return type}}
+
+int i() {
+  struct bitfield { int field:2; };
+  __auto_type j = (struct bitfield){1}.field; // expected-error {{cannot pass bit-field as __auto_type initializer in C}}
+
+}
Index: test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
===
--- test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
+++ test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
@@ -3,9 +3,9 @@
 
 // FIXME: This is in p11 (?) in C++1y.
 void f() {
-  decltype(auto) a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}}
-  if (decltype(auto) b = b) {} // 

[PATCH] D12686: Add support for GCC's '__auto_type' extension.

2015-09-08 Thread Nicholas Allegra via cfe-commits
comex created this revision.
comex added a subscriber: cfe-commits.
Herald added subscribers: aemerson, klimek.

Add support for GCC's '__auto_type' extension.

As per the GCC manual: https://gcc.gnu.org/onlinedocs/gcc/Typeof.html

Implemented in GCC 4.9, __auto_type is similar to C++11 auto but works in C.
The most compelling use case is for macros; the above manual page explains the
need pretty well, so I won't repeat it here.

This implementation differs from GCC's in also supporting __auto_type in C++,
treating it the same as auto.  I don't see any good reason not to, because
otherwise headers intended to be used from both languages can't use it (you
could use a define that expands to '__auto_type' or 'auto' depending on the
language, but then C++ pre-11 is broken).  However, for sanity's sake, it
prevents using __auto_type instead of auto with C++11+-specific functionality
such as 'decltype(auto)', auto arguments to lambdas, and auto before a trailing
return type.

**It also differs by allowing all of the following (by default, due to reusing
the C++ auto behavior) which GCC rejects: initializing with the value of a bit
field, using '__auto_type *', and declaring multiple variables in one
statement.  (The first of those extends a preexisting difference: GCC does not
allow typeof on a bit field, while Clang currently does.  Arguably a bug, as
the C standard prohibits using sizeof on them.)  Maybe this should be tightened
for the sake of compatibility, although it doesn't otherwise seem harmful to
allow them (the latter two, anyway).  Opinions desired.

Making this work in clang is pretty straightforward: most of the patch is only
needed to fix up diagnostics.

(This is my first patch submission, so please let me know if I've done things
wrong.)


http://reviews.llvm.org/D12686

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/Type.h
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TokenKinds.def
  include/clang/Sema/DeclSpec.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/Type.cpp
  lib/AST/TypePrinter.cpp
  lib/Format/TokenAnnotator.cpp
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/ParseObjc.cpp
  lib/Parse/ParseTentative.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTWriter.cpp
  test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
  test/Sema/auto-type.c
  test/SemaCXX/auto-type-from-cxx.cpp

Index: test/SemaCXX/auto-type-from-cxx.cpp
===
--- /dev/null
+++ test/SemaCXX/auto-type-from-cxx.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
+
+__auto_type a() -> int; // expected-error {{function with trailing return type must specify return type 'auto', not '__auto_type'}}
+int b() {
+  decltype(__auto_type) c = 1; // expected-error {{expected expression}}
+  auto _ = [](__auto_type d) {}; // expected-error {{'__auto_type' not allowed in lambda parameter}}
+  __auto_type e = 2;
+}
+
Index: test/Sema/auto-type.c
===
--- /dev/null
+++ test/Sema/auto-type.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -pedantic -std=c11
+
+__auto_type a = 5; // expected-warning {{'__auto_type' is a GNU extension}}
+__extension__ __auto_type a1 = 5;
+#pragma clang diagnostic ignored "-Wgnu-auto-type"
+__auto_type b = 5.0;
+__auto_type c = 
+__auto_type d = (struct {int a;}) {5};
+_Static_assert(__builtin_types_compatible_p(__typeof(a), int), "");
+__auto_type e = e; // expected-error {{variable 'e' declared with '__auto_type' type cannot appear in its own initializer}}
+
+struct s { __auto_type a; }; // expected-error {{'__auto_type' not allowed in struct member}}
+
+__auto_type f = 1, g = 1.0; // expected-error {{'__auto_type' deduced as 'int' in declaration of 'f' and deduced as 'double' in declaration of 'g'}}
+
+__auto_type a() {} // expected-error {{'__auto_type' not allowed in function return type}}
Index: test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
===
--- test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
+++ test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp
@@ -3,9 +3,9 @@
 
 // FIXME: This is in p11 (?) in C++1y.
 void f() {
-  decltype(auto) a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}}
-  if (decltype(auto) b = b) {} // expected-error {{variable 'b' declared with 'auto' type cannot appear in its own initializer}}
-  decltype(auto) c = ({ decltype(auto) d = c; 0; }); // expected-error {{variable