r199513 - Fix string-literal to char* conversion in overload resolution for C++11

Ismail Pazarbasi ismail.pazarbasi at gmail.com
Fri Jan 24 06:37:38 PST 2014


I have fixed the problem with DeprecatedStringLiteralToCharPtr
initialization. Could you please review changes in r199988 and
r199997?

Thanks!

On Fri, Jan 24, 2014 at 10:41 AM, Ismail Pazarbasi
<ismail.pazarbasi at gmail.com> wrote:
> I didn't know this was failing, sorry for breakage. I will try to
> update the patch. If that can't be done quickly, I can check entire
> conversion sequence, which was working.
>
> On Fri, Jan 24, 2014 at 10:02 AM, Evgeniy Stepanov
> <eugeni.stepanov at gmail.com> wrote:
>> The bot was down until less than a day ago, so no one actually new
>> about the issue. I guess it's ok to wait another day.
>>
>>
>> On Fri, Jan 24, 2014 at 12:55 PM, Chandler Carruth <chandlerc at google.com> wrote:
>>> Can we revert until a fix is ready? 7 days with msan failures is too many.
>>>
>>>
>>> On Thu, Jan 23, 2014 at 8:08 PM, Richard Smith <metafoo at gmail.com> wrote:
>>>>
>>>> Looks like the msan build bot has found a bug here:
>>>>
>>>>
>>>> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap/builds/1844/steps/annotate/logs/stdio
>>>>
>>>> It appears that some path through the code doesn't initialize
>>>> DeprecatedStringLiteralToCharPtr.
>>>>
>>>> On Fri Jan 17 2014 at 1:15:20 PM, Ismail Pazarbasi
>>>> <ismail.pazarbasi at gmail.com> wrote:
>>>>
>>>> Author: ismailp
>>>> Date: Fri Jan 17 15:08:52 2014
>>>> New Revision: 199513
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=199513&view=rev
>>>> Log:
>>>> Fix string-literal to char* conversion in overload resolution for C++11
>>>>
>>>> String literal to char* conversion is deprecated in C++03, and is removed
>>>> in
>>>> C++11. We still accept this conversion in C++11 mode as an extension, if
>>>> we find
>>>> it in the best viable function.
>>>>
>>>>
>>>> Modified:
>>>>     cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>>>     cfe/trunk/lib/Sema/SemaExprCXX.cpp
>>>>     cfe/trunk/lib/Sema/SemaOverload.cpp
>>>>     cfe/trunk/test/SemaCXX/cxx0x-type-convert-construct.cpp
>>>>     cfe/trunk/test/SemaCXX/deprecated.cpp
>>>>     cfe/trunk/test/SemaCXX/overload-0x.cpp
>>>>     cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
>>>>
>>>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=199513&r1=199512&r2=199513&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>>>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jan 17
>>>> 15:08:52 2014
>>>> @@ -4534,6 +4534,9 @@ def ext_array_init_parens : ExtWarn<
>>>>  def warn_deprecated_string_literal_conversion : Warning<
>>>>    "conversion from string literal to %0 is deprecated">,
>>>>    InGroup<CXX11CompatDeprecatedWritableStr>;
>>>> +def ext_deprecated_string_literal_conversion : ExtWarn<
>>>> +  "ISO C++11 does not allow conversion from string literal to %0">,
>>>> +  InGroup<CXX11CompatDeprecatedWritableStr>, SFINAEFailure;
>>>>  def warn_deprecated_string_literal_conversion_c : Warning<
>>>>    "dummy warning to enable -fconst-strings">,
>>>> InGroup<DeprecatedWritableStr>, DefaultIgnore;
>>>>  def err_realimag_invalid_type : Error<"invalid type %0 to %1 operator">;
>>>>
>>>> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=199513&r1=199512&r2=199513&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
>>>> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Jan 17 15:08:52 2014
>>>> @@ -3058,9 +3058,12 @@ Sema::PerformImplicitConversion(Expr *Fr
>>>>                               CK_NoOp, VK, /*BasePath=*/0, CCK).take();
>>>>
>>>>      if (SCS.DeprecatedStringLiteralToCharPtr &&
>>>> -        !getLangOpts().WritableStrings)
>>>> -      Diag(From->getLocStart(),
>>>> diag::warn_deprecated_string_literal_conversion)
>>>> +        !getLangOpts().WritableStrings) {
>>>> +      Diag(From->getLocStart(), getLangOpts().CPlusPlus11
>>>> +           ? diag::ext_deprecated_string_literal_conversion
>>>> +           : diag::warn_deprecated_string_literal_conversion)
>>>>          << ToType.getNonReferenceType();
>>>> +    }
>>>>
>>>>      break;
>>>>    }
>>>>
>>>> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=199513&r1=199512&r2=199513&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
>>>> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri Jan 17 15:08:52 2014
>>>> @@ -1443,7 +1443,6 @@ static bool IsStandardConversion(Sema &S
>>>>
>>>>    // Standard conversions (C++ [conv])
>>>>    SCS.setAsIdentityConversion();
>>>> -  SCS.DeprecatedStringLiteralToCharPtr = false;
>>>>    SCS.IncompatibleObjC = false;
>>>>    SCS.setFromType(FromType);
>>>>    SCS.CopyConstructor = 0;
>>>> @@ -1542,7 +1541,7 @@ static bool IsStandardConversion(Sema &S
>>>>      FromType = S.Context.getArrayDecayedType(FromType);
>>>>
>>>>      if (S.IsStringLiteralToNonConstPointerConversion(From, ToType)) {
>>>> -      // This conversion is deprecated. (C++ D.4).
>>>> +      // This conversion is deprecated in C++03 (D.4)
>>>>        SCS.DeprecatedStringLiteralToCharPtr = true;
>>>>
>>>>        // For the purpose of ranking in overload resolution
>>>> @@ -3259,18 +3258,15 @@ Sema::DiagnoseMultipleUserDefinedConvers
>>>>      IsUserDefinedConversion(*this, From, ToType, ICS.UserDefined,
>>>>                              CandidateSet, false, false);
>>>>    if (OvResult == OR_Ambiguous)
>>>> -    Diag(From->getLocStart(),
>>>> -         diag::err_typecheck_ambiguous_condition)
>>>> -          << From->getType() << ToType << From->getSourceRange();
>>>> +    Diag(From->getLocStart(), diag::err_typecheck_ambiguous_condition)
>>>> +        << From->getType() << ToType << From->getSourceRange();
>>>>    else if (OvResult == OR_No_Viable_Function && !CandidateSet.empty()) {
>>>>      if (!RequireCompleteType(From->getLocStart(), ToType,
>>>> -
>>>> diag::err_typecheck_nonviable_condition_incomplete,
>>>> +
>>>> diag::err_typecheck_nonviable_condition_incomplete,
>>>>                               From->getType(), From->getSourceRange()))
>>>> -      Diag(From->getLocStart(),
>>>> -           diag::err_typecheck_nonviable_condition)
>>>> -           << From->getType() << From->getSourceRange() << ToType;
>>>> -  }
>>>> -  else
>>>> +      Diag(From->getLocStart(), diag::err_typecheck_nonviable_condition)
>>>> +          << From->getType() << From->getSourceRange() << ToType;
>>>> +  } else
>>>>      return false;
>>>>    CandidateSet.NoteCandidates(*this, OCD_AllCandidates, From);
>>>>    return true;
>>>> @@ -3280,37 +3276,43 @@ Sema::DiagnoseMultipleUserDefinedConvers
>>>>  /// of two user-defined conversion sequences to determine whether any
>>>> ordering
>>>>  /// is possible.
>>>>  static ImplicitConversionSequence::CompareKind
>>>> -compareConversionFunctions(Sema &S,
>>>> -                           FunctionDecl *Function1,
>>>> +compareConversionFunctions(Sema &S, FunctionDecl *Function1,
>>>>                             FunctionDecl *Function2) {
>>>>    if (!S.getLangOpts().ObjC1 || !S.getLangOpts().CPlusPlus11)
>>>>      return ImplicitConversionSequence::Indistinguishable;
>>>> -
>>>> +
>>>>    // Objective-C++:
>>>>    //   If both conversion functions are implicitly-declared conversions
>>>> from
>>>> -  //   a lambda closure type to a function pointer and a block pointer,
>>>> +  //   a lambda closure type to a function pointer and a block pointer,
>>>>    //   respectively, always prefer the conversion to a function pointer,
>>>>    //   because the function pointer is more lightweight and is more
>>>> likely
>>>>    //   to keep code working.
>>>>    CXXConversionDecl *Conv1 = dyn_cast<CXXConversionDecl>(Function1);
>>>>    if (!Conv1)
>>>>      return ImplicitConversionSequence::Indistinguishable;
>>>> -
>>>> +
>>>>    CXXConversionDecl *Conv2 = dyn_cast<CXXConversionDecl>(Function2);
>>>>    if (!Conv2)
>>>>      return ImplicitConversionSequence::Indistinguishable;
>>>> -
>>>> +
>>>>    if (Conv1->getParent()->isLambda() && Conv2->getParent()->isLambda()) {
>>>>      bool Block1 = Conv1->getConversionType()->isBlockPointerType();
>>>>      bool Block2 = Conv2->getConversionType()->isBlockPointerType();
>>>>      if (Block1 != Block2)
>>>> -      return Block1? ImplicitConversionSequence::Worse
>>>> -                   : ImplicitConversionSequence::Better;
>>>> +      return Block1 ? ImplicitConversionSequence::Worse
>>>> +                    : ImplicitConversionSequence::Better;
>>>>    }
>>>>
>>>>    return ImplicitConversionSequence::Indistinguishable;
>>>>  }
>>>> -
>>>> +
>>>> +static bool hasDeprecatedStringLiteralToCharPtrConversion(
>>>> +    const ImplicitConversionSequence &ICS) {
>>>> +  return (ICS.isStandard() &&
>>>> ICS.Standard.DeprecatedStringLiteralToCharPtr) ||
>>>> +         (ICS.isUserDefined() &&
>>>> +          ICS.UserDefined.Before.DeprecatedStringLiteralToCharPtr);
>>>> +}
>>>> +
>>>>  /// CompareImplicitConversionSequences - Compare two implicit
>>>>  /// conversion sequences to determine whether one is better than the
>>>>  /// other or if they are indistinguishable (C++ 13.3.3.2).
>>>> @@ -3333,6 +3335,32 @@ CompareImplicitConversionSequences(Sema
>>>>    //   described in 13.3.3.2, the ambiguous conversion sequence is
>>>>    //   treated as a user-defined sequence that is indistinguishable
>>>>    //   from any other user-defined conversion sequence.
>>>> +
>>>> +  // String literal to 'char *' conversion has been deprecated in C++03.
>>>> It has
>>>> +  // been removed from C++11. We still accept this conversion, if it
>>>> happens at
>>>> +  // the best viable function. Otherwise, this conversion is considered
>>>> worse
>>>> +  // than ellipsis conversion. Consider this as an extension; this is not
>>>> in the
>>>> +  // standard. For example:
>>>> +  //
>>>> +  // int &f(...);    // #1
>>>> +  // void f(char*);  // #2
>>>> +  // void g() { int &r = f("foo"); }
>>>> +  //
>>>> +  // In C++03, we pick #2 as the best viable function.
>>>> +  // In C++11, we pick #1 as the best viable function, because ellipsis
>>>> +  // conversion is better than string-literal to char* conversion (since
>>>> there
>>>> +  // is no such conversion in C++11). If there was no #1 at all or #1
>>>> couldn't
>>>> +  // convert arguments, #2 would be the best viable function in C++11.
>>>> +  // If the best viable function has this conversion, a warning will be
>>>> issued
>>>> +  // in C++03, or an ExtWarn (+SFINAE failure) will be issued in C++11.
>>>> +
>>>> +  if (S.getLangOpts().CPlusPlus11 && !S.getLangOpts().WritableStrings &&
>>>> +      hasDeprecatedStringLiteralToCharPtrConversion(ICS1) !=
>>>> +      hasDeprecatedStringLiteralToCharPtrConversion(ICS2))
>>>> +    return hasDeprecatedStringLiteralToCharPtrConversion(ICS1)
>>>> +               ? ImplicitConversionSequence::Worse
>>>> +               : ImplicitConversionSequence::Better;
>>>> +
>>>>    if (ICS1.getKindRank() < ICS2.getKindRank())
>>>>      return ImplicitConversionSequence::Better;
>>>>    if (ICS2.getKindRank() < ICS1.getKindRank())
>>>> @@ -4244,6 +4272,7 @@ TryReferenceInit(Sema &S, Expr *Init, Qu
>>>>        ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier =
>>>> false;
>>>>        ICS.Standard.ObjCLifetimeConversionBinding =
>>>> ObjCLifetimeConversion;
>>>>        ICS.Standard.CopyConstructor = 0;
>>>> +      ICS.Standard.DeprecatedStringLiteralToCharPtr = false;
>>>>
>>>>        // Nothing more to do: the inaccessibility/ambiguity check for
>>>>        // derived-to-base conversions is suppressed when we're
>>>> @@ -4318,6 +4347,7 @@ TryReferenceInit(Sema &S, Expr *Init, Qu
>>>>      ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = false;
>>>>      ICS.Standard.ObjCLifetimeConversionBinding = ObjCLifetimeConversion;
>>>>      ICS.Standard.CopyConstructor = 0;
>>>> +    ICS.Standard.DeprecatedStringLiteralToCharPtr = false;
>>>>      return ICS;
>>>>    }
>>>>
>>>>
>>>> Modified: cfe/trunk/test/SemaCXX/cxx0x-type-convert-construct.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-type-convert-construct.cpp?rev=199513&r1=199512&r2=199513&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/test/SemaCXX/cxx0x-type-convert-construct.cpp (original)
>>>> +++ cfe/trunk/test/SemaCXX/cxx0x-type-convert-construct.cpp Fri Jan 17
>>>> 15:08:52 2014
>>>> @@ -9,9 +9,9 @@ void f() {
>>>>    Ustr = U"a UTF-32 string"; // expected-error {{assigning to 'char32_t
>>>> *' from incompatible type 'const char32_t [16]'}}
>>>>
>>>>    char *Rstr;
>>>> -  Rstr = R"foo(a raw string)foo"; // expected-warning{{conversion from
>>>> string literal to 'char *' is deprecated}}
>>>> +  Rstr = R"foo(a raw string)foo"; // expected-warning{{ISO C++11 does not
>>>> allow conversion from string literal to 'char *'}}
>>>>    wchar_t *LRstr;
>>>> -  LRstr = LR"foo(a wide raw string)foo"; // expected-warning{{conversion
>>>> from string literal to 'wchar_t *' is deprecated}}
>>>> +  LRstr = LR"foo(a wide raw string)foo"; // expected-warning{{ISO C++11
>>>> does not allow conversion from string literal to 'wchar_t *'}}
>>>>    char *u8Rstr;
>>>>    u8Rstr = u8R"foo(a UTF-8 raw string)foo"; // expected-error {{assigning
>>>> to 'char *' from incompatible type 'const char [19]'}}
>>>>    char16_t *uRstr;
>>>>
>>>> Modified: cfe/trunk/test/SemaCXX/deprecated.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/deprecated.cpp?rev=199513&r1=199512&r2=199513&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/test/SemaCXX/deprecated.cpp (original)
>>>> +++ cfe/trunk/test/SemaCXX/deprecated.cpp Fri Jan 17 15:08:52 2014
>>>> @@ -24,12 +24,15 @@ void stuff() {
>>>>    register int m asm("rbx"); // no-warning
>>>>
>>>>    int k = to_int(n); // no-warning
>>>> -
>>>>    bool b;
>>>>    ++b; // expected-warning {{incrementing expression of type bool is
>>>> deprecated}}
>>>>
>>>> -  // FIXME: This is ill-formed in C++11.
>>>> -  char *p = "foo"; // expected-warning {{conversion from string literal
>>>> to 'char *' is deprecated}}
>>>> +  char *p = "foo";
>>>> +#if __cplusplus < 201103L
>>>> +  // expected-warning at -2 {{conversion from string literal to 'char *' is
>>>> deprecated}}
>>>> +#else
>>>> +  // expected-warning at -4 {{ISO C++11 does not allow conversion from
>>>> string literal to 'char *'}}
>>>> +#endif
>>>>  }
>>>>
>>>>  struct S { int n; };
>>>>
>>>> Modified: cfe/trunk/test/SemaCXX/overload-0x.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overload-0x.cpp?rev=199513&r1=199512&r2=199513&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/test/SemaCXX/overload-0x.cpp (original)
>>>> +++ cfe/trunk/test/SemaCXX/overload-0x.cpp Fri Jan 17 15:08:52 2014
>>>> @@ -1,7 +1,11 @@
>>>> -// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
>>>> +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
>>>> +// RUN: %clang_cc1 -fsyntax-only -verify %s
>>>>
>>>>  namespace test0 {
>>>> -  struct A { // expected-note {{candidate function (the implicit copy
>>>> assignment operator) not viable: 'this' argument has type 'const test0::A',
>>>> but method is not marked const}} expected-note {{candidate function (the
>>>> implicit move assignment operator) not viable: 'this' argument has type
>>>> 'const test0::A', but method is not marked const}}
>>>> +  struct A { // expected-note {{candidate function (the implicit copy
>>>> assignment operator) not viable: 'this' argument has type 'const test0::A',
>>>> but method is not marked const}}
>>>> +#if __cplusplus >= 201103L
>>>> +  // expected-note at -2 {{candidate function (the implicit move assignment
>>>> operator) not viable: 'this' argument has type 'const test0::A', but method
>>>> is not marked const}}
>>>> +#endif
>>>>      A &operator=(void*); // expected-note {{candidate function not
>>>> viable: 'this' argument has type 'const test0::A', but method is not marked
>>>> const}}
>>>>    };
>>>>
>>>> @@ -9,3 +13,79 @@ namespace test0 {
>>>>      a = "help"; // expected-error {{no viable overloaded '='}}
>>>>    }
>>>>  }
>>>> +
>>>> +namespace PR16314 {
>>>> +  void f(char*);
>>>> +  int &f(...);
>>>> +  void x()
>>>> +  {
>>>> +    int &n = f("foo");
>>>> +#if __cplusplus < 201103L
>>>> +    // expected-warning at -2 {{conversion from string literal to 'char *'
>>>> is deprecated}}
>>>> +    // expected-error at -3 {{non-const lvalue reference to type 'int'
>>>> cannot bind to a temporary of type 'void'}}
>>>> +#endif
>>>> +  }
>>>> +}
>>>> +
>>>> +namespace warn_if_best {
>>>> +  int f(char *);
>>>> +  void f(double);
>>>> +  void x()
>>>> +  {
>>>> +    int n = f("foo");
>>>> +#if __cplusplus < 201103L
>>>> +    // expected-warning at -2 {{conversion from string literal to 'char *'
>>>> is deprecated}}
>>>> +#else
>>>> +    // expected-warning at -4 {{ISO C++11 does not allow conversion from
>>>> string literal to 'char *'}}
>>>> +#endif
>>>> +  }
>>>> +}
>>>> +
>>>> +namespace userdefined_vs_illformed {
>>>> +  struct X { X(const char *); };
>>>> +
>>>> +  void *f(char *p); // best for C++03
>>>> +  double f(X x);  // best for C++11
>>>> +  void g()
>>>> +  {
>>>> +    double d = f("foo");
>>>> +#if __cplusplus < 201103L
>>>> +    // expected-warning at -2 {{conversion from string literal to 'char *'
>>>> is deprecated}}
>>>> +    // expected-error at -3 {{cannot initialize a variable of type 'double'
>>>> with an rvalue of type 'void *'}}
>>>> +#endif
>>>> +  }
>>>> +}
>>>> +
>>>> +namespace sfinae_test {
>>>> +  int f(int, char*);
>>>> +
>>>> +  template<int T>
>>>> +  struct S { typedef int type; };
>>>> +
>>>> +  template<>
>>>> +  struct S<sizeof(int)> { typedef void type; };
>>>> +
>>>> +  // C++11: SFINAE failure
>>>> +  // C++03: ok
>>>> +  template<typename T> int cxx11_ignored(T, typename S<sizeof(f(T(),
>>>> "foo"))>::type *);
>>>> +#if __cplusplus < 201103L
>>>> +  // expected-warning at -2 {{conversion from string literal to 'char *' is
>>>> deprecated}}
>>>> +#else
>>>> +  // expected-note at -4 {{candidate template ignored: substitution
>>>> failure}}
>>>> +#endif
>>>> +
>>>> +  // C++11: better than latter
>>>> +  // C++03: worse than latter
>>>> +  template<typename T> void g(T, ...);
>>>> +  template<typename T> int g(T, typename S<sizeof(f(T(), "foo"))>::type
>>>> *);
>>>> +#if __cplusplus < 201103L
>>>> +  // expected-warning at -2 {{conversion from string literal to 'char *' is
>>>> deprecated}}
>>>> +#endif
>>>> +
>>>> +  int a = cxx11_ignored(0, 0);
>>>> +  int b = g(0, 0);
>>>> +#if __cplusplus >= 201103L
>>>> +  // expected-error at -3 {{no matching function for call to
>>>> 'cxx11_ignored'}}
>>>> +  // expected-error at -3 {{cannot initialize a variable of type 'int' with
>>>> an rvalue of type 'void'}}
>>>> +#endif
>>>> +}
>>>>
>>>> Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=199513&r1=199512&r2=199513&view=diff
>>>>
>>>> ==============================================================================
>>>> --- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp (original)
>>>> +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Fri Jan 17
>>>> 15:08:52 2014
>>>> @@ -2608,13 +2608,13 @@ TEST(ReinterpretCast, DoesNotMatchOtherC
>>>>  }
>>>>
>>>>  TEST(FunctionalCast, MatchesSimpleCase) {
>>>> -  std::string foo_class = "class Foo { public: Foo(char*); };";
>>>> +  std::string foo_class = "class Foo { public: Foo(const char*); };";
>>>>    EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello
>>>> world\"); }",
>>>>                        functionalCastExpr()));
>>>>  }
>>>>
>>>>  TEST(FunctionalCast, DoesNotMatchOtherCasts) {
>>>> -  std::string FooClass = "class Foo { public: Foo(char*); };";
>>>> +  std::string FooClass = "class Foo { public: Foo(const char*); };";
>>>>    EXPECT_TRUE(
>>>>        notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\";
>>>> }",
>>>>                   functionalCastExpr()));
>>>>
>>>>
>>>> _______________________________________________
>>>> cfe-commits mailing list
>>>> cfe-commits at cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>>
>>>>
>>>> _______________________________________________
>>>> cfe-commits mailing list
>>>> cfe-commits at cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>>
>>>
>>>
>>> _______________________________________________
>>> cfe-commits mailing list
>>> cfe-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>
>> _______________________________________________
>> 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