r183637 - reverted test

Larisse Voufo lvoufo at google.com
Mon Jun 10 07:17:15 PDT 2013


On Mon, Jun 10, 2013 at 6:02 AM, Rafael EspĂ­ndola <
rafael.espindola at gmail.com> wrote:

> On 10 June 2013 02:50, Larisse Voufo <lvoufo at google.com> wrote:
> > Author: lvoufo
> > Date: Mon Jun 10 01:50:24 2013
> > New Revision: 183637
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=183637&view=rev
> > Log:
> > reverted test
>
> There is a lot more in here than in 183636. Was this an accidental commit?
>

Yes and No. The commit was not accidental. The message, "reverted test",
was accidental.
I tried to clarify that with another commit, under revision r183639.

I was trying my first commits last night, using git-svn, and was running
into unforeseen difficulties using "git svn dcommit". The instructions at
http://llvm.org/docs/GettingStarted.html#for-developers-to-work-with-git-svn
did
not seem to help. I am trying to resolve the issues.



> >
> > Added:
> >     cfe/trunk/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp
> > Modified:
> >     cfe/trunk/lib/Sema/SemaOverload.cpp
> >     cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
> >
> > Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=183637&r1=183636&r2=183637&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
> > +++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Jun 10 01:50:24 2013
> > @@ -5121,6 +5121,130 @@ bool Sema::ICEConvertDiagnoser::match(Qu
> >                                   :
> T->isIntegralOrUnscopedEnumerationType();
> >  }
> >
> > +static ExprResult
> > +diagnoseAmbiguousConversion(Sema &SemaRef, SourceLocation Loc, Expr
> *From,
> > +                            Sema::ContextualImplicitConverter
> &Converter,
> > +                            QualType T, UnresolvedSetImpl
> &ViableConversions) {
> > +
> > +  if (Converter.Suppress)
> > +    return ExprError();
> > +
> > +  Converter.diagnoseAmbiguous(SemaRef, Loc, T) <<
> From->getSourceRange();
> > +  for (unsigned I = 0, N = ViableConversions.size(); I != N; ++I) {
> > +    CXXConversionDecl *Conv =
> > +
>  cast<CXXConversionDecl>(ViableConversions[I]->getUnderlyingDecl());
> > +    QualType ConvTy = Conv->getConversionType().getNonReferenceType();
> > +    Converter.noteAmbiguous(SemaRef, Conv, ConvTy);
> > +  }
> > +  return SemaRef.Owned(From);
> > +}
> > +
> > +static bool
> > +diagnoseNoViableConversion(Sema &SemaRef, SourceLocation Loc, Expr
> *&From,
> > +                           Sema::ContextualImplicitConverter &Converter,
> > +                           QualType T, bool HadMultipleCandidates,
> > +                           UnresolvedSetImpl &ExplicitConversions) {
> > +  if (ExplicitConversions.size() == 1 && !Converter.Suppress) {
> > +    DeclAccessPair Found = ExplicitConversions[0];
> > +    CXXConversionDecl *Conversion =
> > +        cast<CXXConversionDecl>(Found->getUnderlyingDecl());
> > +
> > +    // The user probably meant to invoke the given explicit
> > +    // conversion; use it.
> > +    QualType ConvTy =
> Conversion->getConversionType().getNonReferenceType();
> > +    std::string TypeStr;
> > +    ConvTy.getAsStringInternal(TypeStr, SemaRef.getPrintingPolicy());
> > +
> > +    Converter.diagnoseExplicitConv(SemaRef, Loc, T, ConvTy)
> > +        << FixItHint::CreateInsertion(From->getLocStart(),
> > +                                      "static_cast<" + TypeStr + ">(")
> > +        << FixItHint::CreateInsertion(
> > +               SemaRef.PP.getLocForEndOfToken(From->getLocEnd()), ")");
> > +    Converter.noteExplicitConv(SemaRef, Conversion, ConvTy);
> > +
> > +    // If we aren't in a SFINAE context, build a call to the
> > +    // explicit conversion function.
> > +    if (SemaRef.isSFINAEContext())
> > +      return true;
> > +
> > +    SemaRef.CheckMemberOperatorAccess(From->getExprLoc(), From, 0,
> Found);
> > +    ExprResult Result = SemaRef.BuildCXXMemberCallExpr(From, Found,
> Conversion,
> > +
> HadMultipleCandidates);
> > +    if (Result.isInvalid())
> > +      return true;
> > +    // Record usage of conversion in an implicit cast.
> > +    From = ImplicitCastExpr::Create(SemaRef.Context,
> Result.get()->getType(),
> > +                                    CK_UserDefinedConversion,
> Result.get(), 0,
> > +                                    Result.get()->getValueKind());
> > +  }
> > +  return false;
> > +}
> > +
> > +static bool recordConversion(Sema &SemaRef, SourceLocation Loc, Expr
> *&From,
> > +                             Sema::ContextualImplicitConverter
> &Converter,
> > +                             QualType T, bool HadMultipleCandidates,
> > +                             DeclAccessPair &Found) {
> > +  CXXConversionDecl *Conversion =
> > +      cast<CXXConversionDecl>(Found->getUnderlyingDecl());
> > +  SemaRef.CheckMemberOperatorAccess(From->getExprLoc(), From, 0, Found);
> > +
> > +  QualType ToType =
> Conversion->getConversionType().getNonReferenceType();
> > +  if (!Converter.SuppressConversion) {
> > +    if (SemaRef.isSFINAEContext())
> > +      return true;
> > +
> > +    Converter.diagnoseConversion(SemaRef, Loc, T, ToType)
> > +        << From->getSourceRange();
> > +  }
> > +
> > +  ExprResult Result = SemaRef.BuildCXXMemberCallExpr(From, Found,
> Conversion,
> > +
> HadMultipleCandidates);
> > +  if (Result.isInvalid())
> > +    return true;
> > +  // Record usage of conversion in an implicit cast.
> > +  From = ImplicitCastExpr::Create(SemaRef.Context,
> Result.get()->getType(),
> > +                                  CK_UserDefinedConversion,
> Result.get(), 0,
> > +                                  Result.get()->getValueKind());
> > +  return false;
> > +}
> > +
> > +static ExprResult finishContextualImplicitConversion(
> > +    Sema &SemaRef, SourceLocation Loc, Expr *From,
> > +    Sema::ContextualImplicitConverter &Converter) {
> > +  if (!Converter.match(From->getType()) && !Converter.Suppress)
> > +    Converter.diagnoseNoMatch(SemaRef, Loc, From->getType())
> > +        << From->getSourceRange();
> > +
> > +  return SemaRef.DefaultLvalueConversion(From);
> > +}
> > +
> > +static void
> > +collectViableConversionCandidates(Sema &SemaRef, Expr *From, QualType
> ToType,
> > +                                  UnresolvedSetImpl &ViableConversions,
> > +                                  OverloadCandidateSet &CandidateSet) {
> > +  for (unsigned I = 0, N = ViableConversions.size(); I != N; ++I) {
> > +    DeclAccessPair FoundDecl = ViableConversions[I];
> > +    NamedDecl *D = FoundDecl.getDecl();
> > +    CXXRecordDecl *ActingContext =
> cast<CXXRecordDecl>(D->getDeclContext());
> > +    if (isa<UsingShadowDecl>(D))
> > +      D = cast<UsingShadowDecl>(D)->getTargetDecl();
> > +
> > +    CXXConversionDecl *Conv;
> > +    FunctionTemplateDecl *ConvTemplate;
> > +    if ((ConvTemplate = dyn_cast<FunctionTemplateDecl>(D)))
> > +      Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
> > +    else
> > +      Conv = cast<CXXConversionDecl>(D);
> > +
> > +    if (ConvTemplate)
> > +      SemaRef.AddTemplateConversionCandidate(
> > +          ConvTemplate, FoundDecl, ActingContext, From, ToType,
> CandidateSet);
> > +    else
> > +      SemaRef.AddConversionCandidate(Conv, FoundDecl, ActingContext,
> From,
> > +                                     ToType, CandidateSet);
> > +  }
> > +}
> > +
> >  /// \brief Attempt to convert the given expression to a type which is
> accepted
> >  /// by the given converter.
> >  ///
> > @@ -5148,7 +5272,8 @@ ExprResult Sema::PerformContextualImplic
> >    // Process placeholders immediately.
> >    if (From->hasPlaceholderType()) {
> >      ExprResult result = CheckPlaceholderExpr(From);
> > -    if (result.isInvalid()) return result;
> > +    if (result.isInvalid())
> > +      return result;
> >      From = result.take();
> >    }
> >
> > @@ -5185,119 +5310,142 @@ ExprResult Sema::PerformContextualImplic
> >      return Owned(From);
> >
> >    // Look for a conversion to an integral or enumeration type.
> > -  UnresolvedSet<4> ViableConversions;
> > +  UnresolvedSet<4>
> > +      ViableConversions; // These are *potentially* viable in C++1y.
> >    UnresolvedSet<4> ExplicitConversions;
> >    std::pair<CXXRecordDecl::conversion_iterator,
> > -            CXXRecordDecl::conversion_iterator> Conversions
> > -    =
> cast<CXXRecordDecl>(RecordTy->getDecl())->getVisibleConversionFunctions();
> > +            CXXRecordDecl::conversion_iterator> Conversions =
> > +
>  cast<CXXRecordDecl>(RecordTy->getDecl())->getVisibleConversionFunctions();
> >
> > -  bool HadMultipleCandidates
> > -    = (std::distance(Conversions.first, Conversions.second) > 1);
> > +  bool HadMultipleCandidates =
> > +      (std::distance(Conversions.first, Conversions.second) > 1);
> >
> > -  for (CXXRecordDecl::conversion_iterator
> > -         I = Conversions.first, E = Conversions.second; I != E; ++I) {
> > -    if (CXXConversionDecl *Conversion
> > -          = dyn_cast<CXXConversionDecl>((*I)->getUnderlyingDecl())) {
> > -      if (Converter.match(
> > -              Conversion->getConversionType().getNonReferenceType())) {
> > -        if (Conversion->isExplicit())
> > +  // To check that there is only one target type, in C++1y:
> > +  QualType ToType;
> > +  bool HasUniqueTargetType = true;
> > +
> > +  // Collect explicit or viable (potentially in C++1y) conversions.
> > +  for (CXXRecordDecl::conversion_iterator I = Conversions.first,
> > +                                          E = Conversions.second;
> > +       I != E; ++I) {
> > +    NamedDecl *D = (*I)->getUnderlyingDecl();
> > +    CXXConversionDecl *Conversion;
> > +    FunctionTemplateDecl *ConvTemplate =
> dyn_cast<FunctionTemplateDecl>(D);
> > +    if (ConvTemplate) {
> > +      if (getLangOpts().CPlusPlus1y)
> > +        Conversion =
> cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
> > +      else
> > +        continue; // C++11 does not consider conversion operator
> templates(?).
> > +    } else
> > +      Conversion = cast<CXXConversionDecl>(D);
> > +
> > +    assert((!ConvTemplate || getLangOpts().CPlusPlus1y) &&
> > +           "Conversion operator templates are considered potentially "
> > +           "viable in C++1y");
> > +
> > +    QualType CurToType =
> Conversion->getConversionType().getNonReferenceType();
> > +    if (Converter.match(CurToType) || ConvTemplate) {
> > +
> > +      if (Conversion->isExplicit()) {
> > +        // FIXME: For C++1y, do we need this restriction?
> > +        // cf. diagnoseNoViableConversion()
> > +        if (!ConvTemplate)
> >            ExplicitConversions.addDecl(I.getDecl(), I.getAccess());
> > -        else
> > -          ViableConversions.addDecl(I.getDecl(), I.getAccess());
> > +      } else {
> > +        if (!ConvTemplate && getLangOpts().CPlusPlus1y) {
> > +          if (ToType.isNull())
> > +            ToType = CurToType.getUnqualifiedType();
> > +          else if (HasUniqueTargetType &&
> > +                   (CurToType.getUnqualifiedType() != ToType))
> > +            HasUniqueTargetType = false;
> > +        }
> > +        ViableConversions.addDecl(I.getDecl(), I.getAccess());
> >        }
> >      }
> >    }
> >
> > -  // FIXME: Implement the C++11 rules!
> > -  switch (ViableConversions.size()) {
> > -  case 0:
> > -    if (ExplicitConversions.size() == 1 && !Converter.Suppress) {
> > -      DeclAccessPair Found = ExplicitConversions[0];
> > -      CXXConversionDecl *Conversion
> > -        = cast<CXXConversionDecl>(Found->getUnderlyingDecl());
> > -
> > -      // The user probably meant to invoke the given explicit
> > -      // conversion; use it.
> > -      QualType ConvTy
> > -        = Conversion->getConversionType().getNonReferenceType();
> > -      std::string TypeStr;
> > -      ConvTy.getAsStringInternal(TypeStr, getPrintingPolicy());
> > -
> > -      Converter.diagnoseExplicitConv(*this, Loc, T, ConvTy)
> > -        << FixItHint::CreateInsertion(From->getLocStart(),
> > -                                      "static_cast<" + TypeStr + ">(")
> > -        <<
> FixItHint::CreateInsertion(PP.getLocForEndOfToken(From->getLocEnd()),
> > -                                      ")");
> > -      Converter.noteExplicitConv(*this, Conversion, ConvTy);
> > -
> > -      // If we aren't in a SFINAE context, build a call to the
> > -      // explicit conversion function.
> > -      if (isSFINAEContext())
> > +  if (getLangOpts().CPlusPlus1y) {
> > +    // C++1y [conv]p6:
> > +    // ... An expression e of class type E appearing in such a context
> > +    // is said to be contextually implicitly converted to a specified
> > +    // type T and is well-formed if and only if e can be implicitly
> > +    // converted to a type T that is determined as follows: E is
> searched
> > +    // for conversion functions whose return type is cv T or reference
> > +    // to cv T such that T is allowed by the context. There shall be
> > +    // exactly one such T.
> > +
> > +    // If no unique T is found:
> > +    if (ToType.isNull()) {
> > +      if (diagnoseNoViableConversion(*this, Loc, From, Converter, T,
> > +                                     HadMultipleCandidates,
> > +                                     ExplicitConversions))
> >          return ExprError();
> > +      return finishContextualImplicitConversion(*this, Loc, From,
> Converter);
> > +    }
> >
> > -      CheckMemberOperatorAccess(From->getExprLoc(), From, 0, Found);
> > -      ExprResult Result = BuildCXXMemberCallExpr(From, Found,
> Conversion,
> > -                                                 HadMultipleCandidates);
> > -      if (Result.isInvalid())
> > +    // If more than one unique Ts are found:
> > +    if (!HasUniqueTargetType)
> > +      return diagnoseAmbiguousConversion(*this, Loc, From, Converter, T,
> > +                                         ViableConversions);
> > +
> > +    // If one unique T is found:
> > +    // First, build a candidate set from the previously recorded
> > +    // potentially viable conversions.
> > +    OverloadCandidateSet CandidateSet(Loc);
> > +    collectViableConversionCandidates(*this, From, ToType,
> ViableConversions,
> > +                                      CandidateSet);
> > +
> > +    // Then, perform overload resolution over the candidate set.
> > +    OverloadCandidateSet::iterator Best;
> > +    switch (CandidateSet.BestViableFunction(*this, Loc, Best)) {
> > +    case OR_Success: {
> > +      // Apply this conversion.
> > +      DeclAccessPair Found =
> > +          DeclAccessPair::make(Best->Function,
> Best->FoundDecl.getAccess());
> > +      if (recordConversion(*this, Loc, From, Converter, T,
> > +                           HadMultipleCandidates, Found))
> >          return ExprError();
> > -      // Record usage of conversion in an implicit cast.
> > -      From = ImplicitCastExpr::Create(Context, Result.get()->getType(),
> > -                                      CK_UserDefinedConversion,
> > -                                      Result.get(), 0,
> > -                                      Result.get()->getValueKind());
> > -    }
> > -
> > -    // We'll complain below about a non-integral condition type.
> > -    break;
> > -
> > -  case 1: {
> > -    // Apply this conversion.
> > -    DeclAccessPair Found = ViableConversions[0];
> > -    CheckMemberOperatorAccess(From->getExprLoc(), From, 0, Found);
> > -
> > -    CXXConversionDecl *Conversion
> > -      = cast<CXXConversionDecl>(Found->getUnderlyingDecl());
> > -    QualType ConvTy
> > -      = Conversion->getConversionType().getNonReferenceType();
> > -    if (!Converter.SuppressConversion) {
> > -      if (isSFINAEContext())
> > +      break;
> > +    }
> > +    case OR_Ambiguous:
> > +      return diagnoseAmbiguousConversion(*this, Loc, From, Converter, T,
> > +                                         ViableConversions);
> > +    case OR_No_Viable_Function:
> > +      if (diagnoseNoViableConversion(*this, Loc, From, Converter, T,
> > +                                     HadMultipleCandidates,
> > +                                     ExplicitConversions))
> >          return ExprError();
> > -
> > -      Converter.diagnoseConversion(*this, Loc, T, ConvTy)
> > -        << From->getSourceRange();
> > +    // fall through 'OR_Deleted' case.
> > +    case OR_Deleted:
> > +      // We'll complain below about a non-integral condition type.
> > +      break;
> >      }
> > +  } else {
> > +    switch (ViableConversions.size()) {
> > +    case 0: {
> > +      if (diagnoseNoViableConversion(*this, Loc, From, Converter, T,
> > +                                     HadMultipleCandidates,
> > +                                     ExplicitConversions))
> > +        return ExprError();
> >
> > -    ExprResult Result = BuildCXXMemberCallExpr(From, Found, Conversion,
> > -                                               HadMultipleCandidates);
> > -    if (Result.isInvalid())
> > -      return ExprError();
> > -    // Record usage of conversion in an implicit cast.
> > -    From = ImplicitCastExpr::Create(Context, Result.get()->getType(),
> > -                                    CK_UserDefinedConversion,
> > -                                    Result.get(), 0,
> > -                                    Result.get()->getValueKind());
> > -    break;
> > -  }
> > -
> > -  default:
> > -    if (Converter.Suppress)
> > -      return ExprError();
> > -
> > -    Converter.diagnoseAmbiguous(*this, Loc, T) <<
> From->getSourceRange();
> > -    for (unsigned I = 0, N = ViableConversions.size(); I != N; ++I) {
> > -      CXXConversionDecl *Conv
> > -        =
> cast<CXXConversionDecl>(ViableConversions[I]->getUnderlyingDecl());
> > -      QualType ConvTy = Conv->getConversionType().getNonReferenceType();
> > -      Converter.noteAmbiguous(*this, Conv, ConvTy);
> > +      // We'll complain below about a non-integral condition type.
> > +      break;
> > +    }
> > +    case 1: {
> > +      // Apply this conversion.
> > +      DeclAccessPair Found = ViableConversions[0];
> > +      if (recordConversion(*this, Loc, From, Converter, T,
> > +                           HadMultipleCandidates, Found))
> > +        return ExprError();
> > +      break;
> > +    }
> > +    default:
> > +      return diagnoseAmbiguousConversion(*this, Loc, From, Converter, T,
> > +                                         ViableConversions);
> >      }
> > -    return Owned(From);
> >    }
> >
> > -  if (!Converter.match(From->getType()) && !Converter.Suppress)
> > -    Converter.diagnoseNoMatch(*this, Loc, From->getType())
> > -      << From->getSourceRange();
> > -
> > -  return DefaultLvalueConversion(From);
> > +  return finishContextualImplicitConversion(*this, Loc, From,
> Converter);
> >  }
> >
> >  /// AddOverloadCandidate - Adds the given function to the set of
> >
> > Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=183637&r1=183636&r2=183637&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
> > +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Jun 10
> 01:50:24 2013
> > @@ -2842,7 +2842,6 @@ void Sema::InstantiateFunctionDefinition
> >    if (Function->isInvalidDecl() || Function->isDefined())
> >      return;
> >
> > -
> >    // Never instantiate an explicit specialization except if it is a
> class scope
> >    // explicit specialization.
> >    if (Function->getTemplateSpecializationKind() ==
> TSK_ExplicitSpecialization &&
> >
> > Added: cfe/trunk/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp?rev=183637&view=auto
> >
> ==============================================================================
> > --- cfe/trunk/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp (added)
> > +++ cfe/trunk/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp Mon
> Jun 10 01:50:24 2013
> > @@ -0,0 +1,157 @@
> > +// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only %s
> > +// RUN: %clang_cc1 -std=c++1y %s -verify -DCXX1Y
> > +
> > +// Explicit member declarations behave as in C++11.
> > +
> > +namespace n3323_example {
> > +
> > +  template <class T> class zero_init {
> > +  public:
> > +    zero_init() : val(static_cast<T>(0)) {}
> > +    zero_init(T val) : val(val) {}
> > +
> > +    operator T &() { return val; }     //@13
> > +    operator T() const { return val; } //@14
> > +
> > +  private:
> > +    T val;
> > +  };
> > +
> > +  void Delete() {
> > +    zero_init<int *> p;
> > +    p = new int(7);
> > +    delete p; //@23
> > +    delete (p + 0);
> > +    delete + p;
> > +  }
> > +
> > +  void Switch() {
> > +    zero_init<int> i;
> > +    i = 7;
> > +    switch (i) {} // @31
> > +    switch (i + 0) {}
> > +    switch (+i) {}
> > +  }
> > +}
> > +
> > +#ifdef CXX1Y
> > +#else
> > +//expected-error at 23 {{ambiguous conversion of delete expression of
> type 'zero_init<int *>' to a pointer}}
> > +//expected-note at 13 {{conversion to pointer type 'int *'}}
> > +//expected-note at 14 {{conversion to pointer type 'int *'}}
> > +//expected-error at 31 {{multiple conversions from switch condition type
> 'zero_init<int>' to an integral or enumeration type}}
> > +//expected-note at 13 {{conversion to integral type 'int'}}
> > +//expected-note at 14 {{conversion to integral type 'int'}}
> > +#endif
> > +
> > +namespace extended_examples {
> > +
> > +  struct A0 {
> > +    operator int();      // matching and viable
> > +  };
> > +
> > +  struct A1 {
> > +    operator int() &&;   // matching and not viable
> > +  };
> > +
> > +  struct A2 {
> > +    operator float();    // not matching
> > +  };
> > +
> > +  struct A3 {
> > +    template<typename T> operator T();  // not matching (ambiguous
> anyway)
> > +  };
> > +
> > +  struct A4 {
> > +    template<typename T> operator int();  // not matching (ambiguous
> anyway)
> > +  };
> > +
> > +  struct B1 {
> > +    operator int() &&;  // @70
> > +    operator int();     // @71  -- duplicate declaration with different
> qualifier is not allowed
> > +  };
> > +
> > +  struct B2 {
> > +    operator int() &&;  // matching but not viable
> > +    operator float();   // not matching
> > +  };
> > +
> > +  void foo(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, B2 b2) {
> > +    switch (a0) {}
> > +    switch (a1) {}     // @81 -- fails for different reasons
> > +    switch (a2) {}     // @82
> > +    switch (a3) {}     // @83
> > +    switch (a4) {}     // @84
> > +    switch (b2) {}     // @85 -- fails for different reasons
> > +  }
> > +}
> > +
> > +//expected-error at 71 {{cannot overload a member function without a
> ref-qualifier with a member function with ref-qualifier '&&'}}
> > +//expected-note at 70 {{previous declaration is here}}
> > +//expected-error at 82 {{statement requires expression of integer type
> ('extended_examples::A2' invalid)}}
> > +//expected-error at 83 {{statement requires expression of integer type
> ('extended_examples::A3' invalid)}}
> > +//expected-error at 84 {{statement requires expression of integer type
> ('extended_examples::A4' invalid)}}
> > +
> > +#ifdef CXX1Y
> > +//expected-error at 81 {{statement requires expression of integer type
> ('extended_examples::A1' invalid)}}
> > +//expected-error at 85 {{statement requires expression of integer type
> ('extended_examples::B2' invalid)}}
> > +#else
> > +//expected-error at 81 {{cannot initialize object parameter of type
> 'extended_examples::A1' with an expression of type 'extended_examples::A1'}}
> > +//expected-error at 85 {{cannot initialize object parameter of type
> 'extended_examples::B2' with an expression of type 'extended_examples::B2'}}
> > +#endif
> > +
> > +namespace extended_examples_cxx1y {
> > +
> > +  struct A1 {   // leads to viable match in C++1y, and no viable match
> in C++11
> > +    operator int() &&;                  // matching but not viable
> > +    template <typename T> operator T(); // In C++1y: matching and
> viable, since disambiguated by L.100
> > +  };
> > +
> > +  struct A2 {   // leads to ambiguity in C++1y, and no viable match in
> C++11
> > +    operator int() &&;                    // matching but not viable
> > +    template <typename T> operator int(); // In C++1y: matching but
> ambiguous (disambiguated by L.105).
> > +  };
> > +
> > +  struct B1 {    // leads to one viable match in both cases
> > +    operator int();                  // matching and viable
> > +    template <typename T> operator T(); // In C++1y: matching and
> viable, since disambiguated by L.110
> > +  };
> > +
> > +  struct B2 {    // leads to one viable match in both cases
> > +    operator int();                  // matching and viable
> > +    template <typename T> operator int(); // In C++1y: matching but
> ambiguous, since disambiguated by L.115
> > +  };
> > +
> > +  struct C {    // leads to no match in both cases
> > +    operator float();                  // not matching
> > +    template <typename T> operator T(); // In C++1y: not matching, nor
> viable.
> > +  };
> > +
> > +  struct D {   // leads to viable match in C++1y, and no viable match
> in C++11
> > +    operator int() &&;                  // matching but not viable
> > +    operator float();                   // not matching
> > +    template <typename T> operator T(); // In C++1y: matching and
> viable, since disambiguated by L.125
> > +  };
> > +
> > +
> > +  void foo(A1 a1, A2 a2, B1 b1, B2 b2, C c, D d) {
> > +    switch (a1) {} // @138 --  should presumably call templated
> conversion operator to convert to int.
> > +    switch (a2) {} // @139
> > +    switch (b1) {}
> > +    switch (b2) {}
> > +    switch (c) {}  // @142
> > +    switch (d) {}  // @143
> > +  }
> > +}
> > +
> > +//expected-error at 142 {{statement requires expression of integer type
> ('extended_examples_cxx1y::C' invalid)}}
> > +
> > +#ifdef CXX1Y
> > +//expected-error at 139 {{statement requires expression of integer type
> ('extended_examples_cxx1y::A2' invalid)}}
> > +#else
> > +//expected-error at 138 {{cannot initialize object parameter of type
> 'extended_examples_cxx1y::A1' with an expression of type
> 'extended_examples_cxx1y::A1'}}
> > +//expected-error at 139 {{cannot initialize object parameter of type
> 'extended_examples_cxx1y::A2' with an expression of type
> 'extended_examples_cxx1y::A2'}}
> > +//expected-error at 143 {{cannot initialize object parameter of type
> 'extended_examples_cxx1y::D' with an expression of type
> 'extended_examples_cxx1y::D'}}
> > +#endif
> > +
> > +// FIXME: Extend with more examples, including [expr.const] and
> [expr.new].
> >
> >
> > _______________________________________________
> > cfe-commits mailing list
> > cfe-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130610/c0fc6d63/attachment.html>


More information about the cfe-commits mailing list