]> granicus.if.org Git - clang/commitdiff
Fix some cases where a CK_IntegralCast was being used to convert an lvalue to an
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 27 Oct 2011 22:11:44 +0000 (22:11 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 27 Oct 2011 22:11:44 +0000 (22:11 +0000)
rvalue. An assertion to catch this is in ImpCastExprToType will follow, but
vector operations currently trip over this (due to omitting the usual arithmetic
conversions). Also add an assert to catch missing lvalue-to-rvalue conversions
on the LHS of ->.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143155 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExprMember.cpp
lib/Sema/SemaStmt.cpp
lib/Sema/SemaTemplate.cpp
test/SemaCXX/constant-expression-cxx11.cpp [new file with mode: 0644]

index 5696e2386d56f5fa271d5c501ed47fb797439cd0..da099681cbca44c4037382378dd168d2e9ab5192 100644 (file)
@@ -761,6 +761,7 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow,
                                    QualType Ty,
                                    ExprValueKind VK, ExprObjectKind OK,
                                    const TemplateArgumentListInfo *TemplateArgs = 0) {
+  assert((!isArrow || Base->isRValue()) && "-> base must be a pointer rvalue");
   return MemberExpr::Create(C, Base, isArrow, SS.getWithLocInContext(C),
                             Member, FoundDecl, MemberNameInfo,
                             TemplateArgs, Ty, VK, OK);
index f35b359f57eb1f68f0a2b677a007b21544b800e1..6dcfbbab84740976db6849148142898b3f2b19d1 100644 (file)
@@ -639,6 +639,9 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
 
       // If the LHS is not the same type as the condition, insert an implicit
       // cast.
+      // FIXME: In C++11, the value is a converted constant expression of the
+      // promoted type of the switch condition.
+      Lo = DefaultLvalueConversion(Lo).take();
       Lo = ImpCastExprToType(Lo, CondType, CK_IntegralCast).take();
       CS->setLHS(Lo);
 
@@ -716,8 +719,11 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
                                            Hi->getLocStart(),
                                            diag::warn_case_value_overflow);
 
-        // If the LHS is not the same type as the condition, insert an implicit
+        // If the RHS is not the same type as the condition, insert an implicit
         // cast.
+        // FIXME: In C++11, the value is a converted constant expression of the
+        // promoted type of the switch condition.
+        Hi = DefaultLvalueConversion(Hi).take();
         Hi = ImpCastExprToType(Hi, CondType, CK_IntegralCast).take();
         CR->setRHS(Hi);
 
index d2641888bd933d6875179b175752a20e0c33592d..de0193c61d417b7f179909c6bc5d8b28a6e787f4 100644 (file)
@@ -3743,8 +3743,16 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
   //        enumeration type, integral promotions (4.5) and integral
   //        conversions (4.7) are applied.
   QualType ParamType = InstantiatedParamType;
-  QualType ArgType = Arg->getType();
   if (ParamType->isIntegralOrEnumerationType()) {
+    // FIXME: In C++11, the argument is a converted constant expression of the
+    // type of the template parameter.
+    ExprResult ArgResult = DefaultLvalueConversion(Arg);
+    if (ArgResult.isInvalid())
+      return ExprError();
+    Arg = ArgResult.take();
+
+    QualType ArgType = Arg->getType();
+
     // C++ [temp.arg.nontype]p1:
     //   A template-argument for a non-type, non-template
     //   template-parameter shall be one of:
@@ -3868,6 +3876,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
     return Owned(Arg);
   }
 
+  QualType ArgType = Arg->getType();
   DeclAccessPair FoundResult; // temporary for ResolveOverloadedFunction
 
   // C++0x [temp.arg.nontype]p5 bullets 2, 4 and 6 permit conversion
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
new file mode 100644 (file)
index 0000000..8995570
--- /dev/null
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+template<typename T> constexpr T id(const T &t) { return t; }
+
+struct MemberZero {
+  constexpr int zero() { return 0; }
+};
+
+namespace TemplateArgumentConversion {
+  template<int n> struct IntParam {};
+
+  using IntParam0 = IntParam<0>;
+  // FIXME: This should be accepted once we do constexpr function invocation.
+  using IntParam0 = IntParam<id(0)>; // expected-error {{not an integral constant expression}}
+  using IntParam0 = IntParam<MemberZero().zero>; // expected-error {{did you mean to call it with no arguments?}} expected-error {{not an integral constant expression}}
+}
+
+namespace CaseStatements {
+  void f(int n) {
+    switch (n) {
+    // FIXME: Produce the 'add ()' fixit for this.
+    case MemberZero().zero: // desired-error {{did you mean to call it with no arguments?}} expected-error {{not an integer constant expression}}
+    // FIXME: This should be accepted once we do constexpr function invocation.
+    case id(1): // expected-error {{not an integer constant expression}}
+      return;
+    }
+  }
+}