r183637 - reverted test
Rafael EspĂndola
rafael.espindola at gmail.com
Mon Jun 10 06:02:42 PDT 2013
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?
>
> 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
More information about the cfe-commits
mailing list