Endless operator-> chain causing infinite loop
Richard Smith
richard at metafoo.co.uk
Wed Nov 6 11:48:07 PST 2013
Committed with a few changes as r194161. Thanks!
On Wed, Nov 6, 2013 at 9:20 AM, Rahul Jain <1989.rahuljain at gmail.com> wrote:
> Ping.
>
>
> On Tue, Oct 29, 2013 at 1:12 PM, Rahul Jain <1989.rahuljain at gmail.com>wrote:
>
>> Hi Richard,
>>
>> Thanks for you valuable inputs.
>>
>> I have reworked the patch barring just one particular change you
>> suggested.
>> Here is the patch.
>>
>> Index: lib/Frontend/CompilerInvocation.cpp
>> ===================================================================
>> --- lib/Frontend/CompilerInvocation.cpp (revision 193583)
>>
>> +++ lib/Frontend/CompilerInvocation.cpp (working copy)
>> @@ -1313,6 +1313,8 @@
>> Opts.MathErrno = !Opts.OpenCL && Args.hasArg(OPT_fmath_errno);
>> Opts.InstantiationDepth =
>> getLastArgIntValue(Args, OPT_ftemplate_depth, 256, Diags);
>> + Opts.ArrowDepth =
>> + getLastArgIntValue(Args, OPT_foperator_arrow_depth, 2048, Diags);
>> Opts.ConstexprCallDepth =
>> getLastArgIntValue(Args, OPT_fconstexpr_depth, 512, Diags);
>> Opts.ConstexprStepLimit =
>> Index: lib/Sema/SemaExprCXX.cpp
>> ===================================================================
>> --- lib/Sema/SemaExprCXX.cpp (revision 193583)
>>
>> +++ lib/Sema/SemaExprCXX.cpp (working copy)
>> @@ -5189,7 +5189,17 @@
>> SmallVector<SourceLocation, 8> Locations;
>> CTypes.insert(Context.getCanonicalType(BaseType));
>>
>> + unsigned int ArrowInstantiationCount = 0;
>> while (BaseType->isRecordType()) {
>> + ArrowInstantiationCount++;
>> + if (ArrowInstantiationCount >= getLangOpts().ArrowDepth) {
>>
>> + Diag(OpLoc, diag::err_arrow_instantiation_depth_exceeded)
>> + << getLangOpts().ArrowDepth << Base->getSourceRange();
>> + Diag(OpLoc, diag::note_arrow_instantiation_depth)
>> + << getLangOpts().ArrowDepth;
>> + return ExprError();
>> + }
>> +
>> Result = BuildOverloadedArrowExpr(
>> S, Base, OpLoc,
>> // When in a template specialization and on the first loop
>> iteration,
>> Index: lib/Driver/Tools.cpp
>> ===================================================================
>> --- lib/Driver/Tools.cpp (revision 193583)
>>
>> +++ lib/Driver/Tools.cpp (working copy)
>> @@ -2802,6 +2802,11 @@
>> CmdArgs.push_back(A->getValue());
>> }
>>
>> + if (Arg *A = Args.getLastArg(options::OPT_foperator_arrow_depth_EQ)) {
>> + CmdArgs.push_back("-foperator-arrow-depth");
>> + CmdArgs.push_back(A->getValue());
>> + }
>> +
>> if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_depth_EQ)) {
>> CmdArgs.push_back("-fconstexpr-depth");
>> CmdArgs.push_back(A->getValue());
>> Index: include/clang/Basic/LangOptions.def
>> ===================================================================
>> --- include/clang/Basic/LangOptions.def (revision 193583)
>>
>> +++ include/clang/Basic/LangOptions.def (working copy)
>> @@ -160,6 +160,8 @@
>> ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2,
>> SOB_Undefined,
>> "signed integer overflow handling")
>>
>> +BENIGN_LANGOPT(ArrowDepth, 32, 2048,
>> + "maximum number of operator->s to follow")
>> BENIGN_LANGOPT(InstantiationDepth, 32, 256,
>> "maximum template instantiation depth")
>> BENIGN_LANGOPT(ConstexprCallDepth, 32, 512,
>> Index: include/clang/Basic/DiagnosticSemaKinds.td
>> ===================================================================
>> --- include/clang/Basic/DiagnosticSemaKinds.td (revision 193583)
>>
>> +++ include/clang/Basic/DiagnosticSemaKinds.td (working copy)
>> @@ -2569,6 +2569,11 @@
>> // can handle that case properly.
>> def note_ovl_candidate_non_deduced_mismatch_qualified : Note<
>> "candidate template ignored: could not match %q0 against %q1">;
>> +def err_arrow_instantiation_depth_exceeded : Error<
>> + "arrow operator instantiation exceeded maximum depth of %0">;
>> +def note_arrow_instantiation_depth : Note<
>> + "use -foperator-arrow-depth=N to increase arrow operator
>> instantiation "
>> + "depth">;
>>
>> // Note that we don't treat templates differently for this diagnostic.
>> def note_ovl_candidate_arity : Note<"candidate "
>> Index: include/clang/Driver/Options.td
>> ===================================================================
>> --- include/clang/Driver/Options.td (revision 193583)
>>
>> +++ include/clang/Driver/Options.td (working copy)
>> @@ -775,6 +775,8 @@
>> def ftemplate_depth_ : Joined<["-"], "ftemplate-depth-">, Group<f_Group>;
>> def ftemplate_backtrace_limit_EQ : Joined<["-"],
>> "ftemplate-backtrace-limit=">,
>> Group<f_Group>;
>> +def foperator_arrow_depth_EQ : Joined<["-"], "foperator-arrow-depth=">,
>> + Group<f_Group>;
>> def ftest_coverage : Flag<["-"], "ftest-coverage">, Group<f_Group>;
>> def fvectorize : Flag<["-"], "fvectorize">, Group<f_Group>,
>> HelpText<"Enable the loop vectorization passes">;
>> Index: include/clang/Driver/CC1Options.td
>> ===================================================================
>> --- include/clang/Driver/CC1Options.td (revision 193583)
>>
>> +++ include/clang/Driver/CC1Options.td (working copy)
>> @@ -442,6 +442,8 @@
>> HelpText<"Default type visibility">;
>> def ftemplate_depth : Separate<["-"], "ftemplate-depth">,
>> HelpText<"Maximum depth of recursive template instantiation">;
>> +def foperator_arrow_depth : Separate<["-"], "foperator-arrow-depth">,
>> + HelpText<"Maximum depth of arrow operator instantiation">;
>> def fconstexpr_depth : Separate<["-"], "fconstexpr-depth">,
>> HelpText<"Maximum depth of recursive constexpr function calls">;
>> def fconstexpr_steps : Separate<["-"], "fconstexpr-steps">,
>> Index: docs/UsersManual.rst
>> ===================================================================
>> --- docs/UsersManual.rst (revision 193583)
>> +++ docs/UsersManual.rst (working copy)
>> @@ -1292,6 +1292,11 @@
>> Sets the limit for recursively nested template instantiations to N.
>> The
>> default is 1024.
>>
>> +.. option:: -foperator-arrow-depth=N
>> +
>> + Sets the limit for arrow operator instantiations to N. The
>> + default is 2048.
>> +
>> .. _objc:
>>
>> Objective-C Language Features
>>
>>
>>
>> Here is the test case which I have worked out:
>>
>> // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -DMAX=10
>> -foperator-arrow-depth=10
>> // RUN: %clang -std=c++11 -fsyntax-only -Xclang -verify %s -DMAX=10
>> -foperator-arrow-depth=10
>>
>>
>> template< int n >
>> struct a {
>> a< n+1 > operator->()
>> {
>> return a< n+1 >();
>> }
>> };
>>
>> int foo() {
>> a<0>()->x; \
>> // expected-error{{arrow operator instantiation exceeded maximum depth of
>> 10}} \
>> // expected-note {{use -foperator-arrow-depth=N to increase arrow
>> operator instantiation depth}}
>> }
>>
>> Please suggest improvements.
>>
>> A couple of things on which your inputs would be appreciated are:
>>
>> 1) ""Please don't use the word 'instantiation' here.""
>>
>>
>> This comment was implied for note def name/error def name/note string
>> being printed/error string being printed??
>>
>> Please suggest some alternatives for the same.
>>
>
I've reworded this a little.
> 2) "Have you considered including notes pointing at the sequence of
>> operator-> functions we called, and the corresponding types? This might not
>> be obvious."
>>
>> By this you mean backtrace right, similar to the option
>> -ftemplate-backtrace-limit=N? If yes, I did think about it, but was
>> concerned about the implementation difficulty. If necessary I will work it
>> out.
>>
>
I've added this. We now produce:
<stdin>:1:81: error: use of 'operator->' on type 'Ptr<int>' would invoke a
sequence of more than 256 'operator->' calls
template<typename T> struct Ptr { Ptr<T*> operator->(); }; Ptr<int> p; int
n = p->n;
~^
<stdin>:1:43: note: 'operator->' declared here produces an object of type
'Ptr<int *>'
template<typename T> struct Ptr { Ptr<T*> operator->(); }; Ptr<int> p; int
n = p->n;
^
<stdin>:1:43: note: 'operator->' declared here produces an object of type
'Ptr<int **>'
<stdin>:1:43: note: 'operator->' declared here produces an object of type
'Ptr<int ***>'
<stdin>:1:43: note: 'operator->' declared here produces an object of type
'Ptr<int ****>'
<stdin>:1:43: note: (skipping 248 'operator->'s in backtrace)
<stdin>:1:43: note: 'operator->' declared here produces an object of type
'Ptr<int
*************************************************************************************************************************************************************************************************************************************************************>'
<stdin>:1:43: note: 'operator->' declared here produces an object of type
'Ptr<int
**************************************************************************************************************************************************************************************************************************************************************>'
<stdin>:1:43: note: 'operator->' declared here produces an object of type
'Ptr<int
***************************************************************************************************************************************************************************************************************************************************************>'
<stdin>:1:43: note: 'operator->' declared here produces an object of type
'Ptr<int
****************************************************************************************************************************************************************************************************************************************************************>'
<stdin>:1:81: note: use -foperator-arrow-depth=N to increase 'operator->'
limit
template<typename T> struct Ptr { Ptr<T*> operator->(); }; Ptr<int> p; int
n = p->n;
^
I also reduced the depth limit to 256 to match the bracket limit (recursive
AST visitors might otherwise hit stack overflows when analyzing a long
operator-> chain).
> Thanks,
>> Rahul
>>
>>
>>
>>
>>
>> On Mon, Oct 28, 2013 at 11:55 PM, Richard Smith <richard at metafoo.co.uk>wrote:
>>
>>> On Sun, Oct 27, 2013 at 2:10 PM, Rahul Jain <1989.rahuljain at gmail.com>wrote:
>>>
>>>> Hi,
>>>>
>>>> Thanks a lot Arthur and Richard for your valuable comments. Feels great
>>>> when a beginner is supported to such an extent.
>>>>
>>>> As per your comments I have reworked the patch. Here is the revised
>>>> one. Please take a look for feedback.
>>>>
>>>> Index: lib/Frontend/CompilerInvocation.cpp
>>>> ===================================================================
>>>> --- lib/Frontend/CompilerInvocation.cpp (revision 193504)
>>>> +++ lib/Frontend/CompilerInvocation.cpp (working copy)
>>>> @@ -1313,6 +1313,8 @@
>>>> Opts.MathErrno = !Opts.OpenCL && Args.hasArg(OPT_fmath_errno);
>>>> Opts.InstantiationDepth =
>>>> getLastArgIntValue(Args, OPT_ftemplate_depth, 256, Diags);
>>>> + Opts.ArrowDepth =
>>>> + getLastArgIntValue(Args, OPT_foperator_arrow_depth, 2048, Diags);
>>>> Opts.ConstexprCallDepth =
>>>> getLastArgIntValue(Args, OPT_fconstexpr_depth, 512, Diags);
>>>> Opts.ConstexprStepLimit =
>>>> Index: lib/Driver/Tools.cpp
>>>> ===================================================================
>>>> --- lib/Driver/Tools.cpp (revision 193504)
>>>> +++ lib/Driver/Tools.cpp (working copy)
>>>> @@ -2802,6 +2802,11 @@
>>>> CmdArgs.push_back(A->getValue());
>>>> }
>>>>
>>>> + if (Arg *A = Args.getLastArg(options::OPT_foperator_arrow_depth_EQ))
>>>> {
>>>> + CmdArgs.push_back("-foperator-arrow-depth");
>>>> + CmdArgs.push_back(A->getValue());
>>>> + }
>>>> +
>>>> if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_depth_EQ)) {
>>>> CmdArgs.push_back("-fconstexpr-depth");
>>>> CmdArgs.push_back(A->getValue());
>>>> Index: lib/Sema/SemaExprCXX.cpp
>>>> ===================================================================
>>>> --- lib/Sema/SemaExprCXX.cpp (revision 193504)
>>>> +++ lib/Sema/SemaExprCXX.cpp (working copy)
>>>> @@ -5189,7 +5189,17 @@
>>>> SmallVector<SourceLocation, 8> Locations;
>>>> CTypes.insert(Context.getCanonicalType(BaseType));
>>>>
>>>> + unsigned int Arrow_instantiation_count = 0;
>>>>
>>>
>>> This should be CamelCase, without underscores.
>>>
>>>
>>>> while (BaseType->isRecordType()) {
>>>> + Arrow_instantiation_count++;
>>>> + if (Arrow_instantiation_count >= getLangOpts().ArrowDepth) {
>>>> + Diag(OpLoc, diag::err_arrow_instantiation_depth_exceeded)
>>>> + << getLangOpts().ArrowDepth << Base->getSourceRange();
>>>> + Diag(OpLoc, diag::note_arrow_instantiation_depth)
>>>> + << getLangOpts().ArrowDepth;
>>>> + return ExprError();
>>>>
>>>
>>> The body of this 'if' should be indented by two more spaces.
>>>
>>>
>>>> + }
>>>> +
>>>> Result = BuildOverloadedArrowExpr(
>>>> S, Base, OpLoc,
>>>> // When in a template specialization and on the first loop
>>>> iteration,
>>>> Index: include/clang/Basic/LangOptions.def
>>>> ===================================================================
>>>> --- include/clang/Basic/LangOptions.def (revision 193504)
>>>> +++ include/clang/Basic/LangOptions.def (working copy)
>>>> @@ -160,6 +160,8 @@
>>>> ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2,
>>>> SOB_Undefined,
>>>> "signed integer overflow handling")
>>>>
>>>> +BENIGN_LANGOPT(ArrowDepth, 32, 2048,
>>>> + "maximum number of operator->s to follow")
>>>> BENIGN_LANGOPT(InstantiationDepth, 32, 256,
>>>> "maximum template instantiation depth")
>>>> BENIGN_LANGOPT(ConstexprCallDepth, 32, 512,
>>>> Index: include/clang/Basic/DiagnosticSemaKinds.td
>>>> ===================================================================
>>>> --- include/clang/Basic/DiagnosticSemaKinds.td (revision 193504)
>>>> +++ include/clang/Basic/DiagnosticSemaKinds.td (working copy)
>>>> @@ -2569,6 +2569,11 @@
>>>> // can handle that case properly.
>>>> def note_ovl_candidate_non_deduced_mismatch_qualified : Note<
>>>> "candidate template ignored: could not match %q0 against %q1">;
>>>> +def err_arrow_instantiation_depth_exceeded : Error<
>>>> + "arrow operator instantiation exceeded maximum depth of %0">;
>>>> +def note_arrow_instantiation_depth : Note<
>>>> + "use -foperator-arrow-depth=N to increase arrow operator
>>>> instantiation "
>>>> + "depth">;
>>>>
>>>
>>> Please don't use the word 'instantiation' here.
>>>
>>> Have you considered including notes pointing at the sequence of
>>> operator-> functions we called, and the corresponding types? This might not
>>> be obvious.
>>>
>>>
>>>> // Note that we don't treat templates differently for this diagnostic.
>>>> def note_ovl_candidate_arity : Note<"candidate "
>>>> Index: include/clang/Driver/CC1Options.td
>>>> ===================================================================
>>>> --- include/clang/Driver/CC1Options.td (revision 193504)
>>>> +++ include/clang/Driver/CC1Options.td (working copy)
>>>> @@ -442,6 +442,8 @@
>>>> HelpText<"Default type visibility">;
>>>> def ftemplate_depth : Separate<["-"], "ftemplate-depth">,
>>>> HelpText<"Maximum depth of recursive template instantiation">;
>>>> +def foperator_arrow_depth : Separate<["-"], "foperator-arrow-depth">,
>>>> + HelpText<"Maximum depth of arrow operator instantiation">;
>>>> def fconstexpr_depth : Separate<["-"], "fconstexpr-depth">,
>>>> HelpText<"Maximum depth of recursive constexpr function calls">;
>>>> def fconstexpr_steps : Separate<["-"], "fconstexpr-steps">,
>>>> Index: include/clang/Driver/Options.td
>>>> ===================================================================
>>>> --- include/clang/Driver/Options.td (revision 193504)
>>>> +++ include/clang/Driver/Options.td (working copy)
>>>> @@ -775,6 +775,8 @@
>>>> def ftemplate_depth_ : Joined<["-"], "ftemplate-depth-">,
>>>> Group<f_Group>;
>>>> def ftemplate_backtrace_limit_EQ : Joined<["-"],
>>>> "ftemplate-backtrace-limit=">,
>>>> Group<f_Group>;
>>>> +def foperator_arrow_depth_EQ : Joined<["-"], "foperator-arrow-depth=">,
>>>> + Group<f_Group>;
>>>> def ftest_coverage : Flag<["-"], "ftest-coverage">, Group<f_Group>;
>>>> def fvectorize : Flag<["-"], "fvectorize">, Group<f_Group>,
>>>> HelpText<"Enable the loop vectorization passes">;
>>>>
>>>>
>>>> Attaching the gcc testsuite test case too for reference.
>>>>
>>>
>>> Please don't mail code from GCC here.
>>>
>>> Instead, you'll need to craft a test case for our test suite. You can
>>> take inspiration from
>>>
>>> test/SemaCXX/constexpr-depth.cpp
>>> test/SemaTemplate/instantiation-depth.cpp
>>>
>>>
>>>> How do I add the flag to the documentation?
>>>>
>>>
>>> Modify docs/UsersManual.rst
>>>
>>> Thank you for working on this!
>>>
>>>
>>>> Thanks,
>>>> Rahul
>>>>
>>>>
>>>> On Sat, Oct 26, 2013 at 12:14 AM, Richard Smith <richard at metafoo.co.uk>wrote:
>>>>
>>>>> On Fri, Oct 25, 2013 at 9:06 AM, Arthur O'Dwyer <
>>>>> arthur.j.odwyer at gmail.com> wrote:
>>>>>
>>>>>> IMHO, it would be better to remove the command-line option, and just
>>>>>> set the (hard-coded) limit to 2048 or something else of that general
>>>>>> order of magnitude. I can't think of any valid use for deeply nested
>>>>>> operator->s; it's not like recursive template instantiation, where you
>>>>>> might want to use a higher limit to implement a useful behavior.
>>>>>>
>>>>>
>>>>> The "usual" (albeit very rare) use is to get around the recursive
>>>>> template instantiation depth limit.
>>>>>
>>>>>
>>>>>> Therefore, setting the limit to something in the thousands ought to be
>>>>>> good enough until someone legitimately runs into the limit; and in the
>>>>>> meantime, we're not polluting the command-line docs with obscure and
>>>>>> useless options.
>>>>>>
>>>>>
>>>>> I don't see any problem with setting the default to a higher value,
>>>>> like maybe 2048.
>>>>>
>>>>>
>>>>>> Also FWIW, I do think a DR ought to be opened to make this an explicit
>>>>>> implementation limit in the Standard... but I'm not volunteering. :)
>>>>>>
>>>>>> my $.02,
>>>>>> –Arthur
>>>>>>
>>>>>>
>>>>>> On Fri, Oct 25, 2013 at 7:45 AM, Rahul Jain <1989.rahuljain at gmail.com>
>>>>>> wrote:
>>>>>> >
>>>>>> > Hi,
>>>>>> >
>>>>>> > This is with reference to the below discussion thread:
>>>>>> >
>>>>>> >
>>>>>> http://clang-developers.42468.n3.nabble.com/Endless-operator-gt-chain-causing-infinite-loop-td4035258.html
>>>>>> >
>>>>>> > I have tried to implement a command line argument to handle the
>>>>>> issue.
>>>>>> >
>>>>>> > The patch for the same is below:
>>>>>> >
>>>>>> > Index: lib/Driver/Tools.cpp
>>>>>> > ===================================================================
>>>>>> > --- lib/Driver/Tools.cpp (revision 193400)
>>>>>> > +++ lib/Driver/Tools.cpp (working copy)
>>>>>> > @@ -2802,6 +2802,12 @@
>>>>>> > CmdArgs.push_back(A->getValue());
>>>>>> > }
>>>>>> >
>>>>>> > + if (Arg *A = Args.getLastArg(options::OPT_foperatorarrow_depth_,
>>>>>> > +
>>>>>> options::OPT_foperatorarrow_depth_EQ)) {
>>>>>> > + CmdArgs.push_back("-foperatorarrow-depth");
>>>>>>
>>>>>
>>>>> Please use foperator_arrow_depth and -foperator-arrow-depth.
>>>>>
>>>>>
>>>>>> > + CmdArgs.push_back(A->getValue());
>>>>>> > + }
>>>>>> > +
>>>>>> > if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_depth_EQ)) {
>>>>>> > CmdArgs.push_back("-fconstexpr-depth");
>>>>>> > CmdArgs.push_back(A->getValue());
>>>>>> > Index: lib/Frontend/CompilerInvocation.cpp
>>>>>> > ===================================================================
>>>>>> > --- lib/Frontend/CompilerInvocation.cpp (revision 193400)
>>>>>> > +++ lib/Frontend/CompilerInvocation.cpp (working copy)
>>>>>> > @@ -1313,6 +1313,8 @@
>>>>>> > Opts.MathErrno = !Opts.OpenCL && Args.hasArg(OPT_fmath_errno);
>>>>>> > Opts.InstantiationDepth =
>>>>>> > getLastArgIntValue(Args, OPT_ftemplate_depth, 256, Diags);
>>>>>> > + Opts.ArrowDepth =
>>>>>> > + getLastArgIntValue(Args, OPT_foperatorarrow_depth, 256,
>>>>>> Diags);
>>>>>> > Opts.ConstexprCallDepth =
>>>>>> > getLastArgIntValue(Args, OPT_fconstexpr_depth, 512, Diags);
>>>>>> > Opts.ConstexprStepLimit =
>>>>>> > Index: lib/Sema/SemaExprCXX.cpp
>>>>>> > ===================================================================
>>>>>> > --- lib/Sema/SemaExprCXX.cpp (revision 193400)
>>>>>> > +++ lib/Sema/SemaExprCXX.cpp (working copy)
>>>>>> > @@ -5188,8 +5188,19 @@
>>>>>> > llvm::SmallPtrSet<CanQualType,8> CTypes;
>>>>>> > SmallVector<SourceLocation, 8> Locations;
>>>>>> > CTypes.insert(Context.getCanonicalType(BaseType));
>>>>>> > +
>>>>>> > + static unsigned int arrow_instantiation_count = 0;
>>>>>>
>>>>>
>>>>> This should not be static, and the name should follow the coding
>>>>> convention:
>>>>>
>>>>>
>>>>> http://llvm.org/docs/CodingStandards.html#name-types-functions-variables-and-enumerators-properly
>>>>>
>>>>> > + while (BaseType->isRecordType()) {
>>>>>> > + arrow_instantiation_count++;
>>>>>> > + if (arrow_instantiation_count >= getLangOpts().ArrowDepth) {
>>>>>> > + Diag(OpLoc,diag::err_arrow_instantiation_depth_exceeded)
>>>>>>
>>>>>
>>>>> Space after comma.
>>>>>
>>>>>
>>>>>> > + << getLangOpts().ArrowDepth
>>>>>> > + << Base->getSourceRange();
>>>>>> > + Diag(OpLoc, diag::note_arrow_instantiation_depth)
>>>>>> > + << getLangOpts().ArrowDepth;
>>>>>> > + return ExprError();
>>>>>>
>>>>>
>>>>> Indentation is strange here.
>>>>>
>>>>>
>>>>>> > + }
>>>>>> >
>>>>>> > - while (BaseType->isRecordType()) {
>>>>>> > Result = BuildOverloadedArrowExpr(
>>>>>> > S, Base, OpLoc,
>>>>>> > // When in a template specialization and on the first
>>>>>> loop
>>>>>> > iteration,
>>>>>> > Index: include/clang/Basic/DiagnosticSemaKinds.td
>>>>>> > ===================================================================
>>>>>> > --- include/clang/Basic/DiagnosticSemaKinds.td (revision 193400)
>>>>>> > +++ include/clang/Basic/DiagnosticSemaKinds.td (working copy)
>>>>>> > @@ -2561,6 +2561,11 @@
>>>>>> > // can handle that case properly.
>>>>>> > def note_ovl_candidate_non_deduced_mismatch_qualified : Note<
>>>>>> > "candidate template ignored: could not match %q0 against %q1">;
>>>>>> > +def err_arrow_instantiation_depth_exceeded : Error<
>>>>>> > + "arrow operator instantiation exceeded maximum depth of %0">,
>>>>>> > + DefaultFatal, NoSFINAE;
>>>>>>
>>>>>
>>>>> We don't need this to be fatal.
>>>>>
>>>>>
>>>>>> > +def note_arrow_instantiation_depth : Note<
>>>>>> > + "use -foperatorarrow-depth=N to increase arrow operator
>>>>>> instantiation
>>>>>> > depth">;
>>>>>> >
>>>>>> > // Note that we don't treat templates differently for this
>>>>>> diagnostic.
>>>>>> > def note_ovl_candidate_arity : Note<"candidate "
>>>>>> > Index: include/clang/Basic/LangOptions.def
>>>>>> > ===================================================================
>>>>>> > --- include/clang/Basic/LangOptions.def (revision 193400)
>>>>>> > +++ include/clang/Basic/LangOptions.def (working copy)
>>>>>> > @@ -160,6 +160,8 @@
>>>>>> > ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2,
>>>>>> > SOB_Undefined,
>>>>>> > "signed integer overflow handling")
>>>>>> >
>>>>>> > +BENIGN_LANGOPT(ArrowDepth, 32, 256,
>>>>>> > + "maximum arrow instantiation depth")
>>>>>>
>>>>>
>>>>> "instantiation" is not correct here. Maybe "maximum number of
>>>>> operator->s to follow"?
>>>>>
>>>>>
>>>>>> > BENIGN_LANGOPT(InstantiationDepth, 32, 256,
>>>>>> > "maximum template instantiation depth")
>>>>>> > BENIGN_LANGOPT(ConstexprCallDepth, 32, 512,
>>>>>> > Index: include/clang/Driver/CC1Options.td
>>>>>> > ===================================================================
>>>>>> > --- include/clang/Driver/CC1Options.td (revision 193400)
>>>>>> > +++ include/clang/Driver/CC1Options.td (working copy)
>>>>>> > @@ -442,6 +442,8 @@
>>>>>> > HelpText<"Default type visibility">;
>>>>>> > def ftemplate_depth : Separate<["-"], "ftemplate-depth">,
>>>>>> > HelpText<"Maximum depth of recursive template instantiation">;
>>>>>> > +def foperatorarrow_depth : Separate<["-"], "foperatorarrow-depth">,
>>>>>> > + HelpText<"Maximum depth of arrow operator instantiation">;
>>>>>> > def fconstexpr_depth : Separate<["-"], "fconstexpr-depth">,
>>>>>> > HelpText<"Maximum depth of recursive constexpr function calls">;
>>>>>> > def fconstexpr_steps : Separate<["-"], "fconstexpr-steps">,
>>>>>> > Index: include/clang/Driver/Options.td
>>>>>> > ===================================================================
>>>>>> > --- include/clang/Driver/Options.td (revision 193400)
>>>>>> > +++ include/clang/Driver/Options.td (working copy)
>>>>>> > @@ -775,6 +775,8 @@
>>>>>> > def ftemplate_depth_ : Joined<["-"], "ftemplate-depth-">,
>>>>>> Group<f_Group>;
>>>>>> > def ftemplate_backtrace_limit_EQ : Joined<["-"],
>>>>>> > "ftemplate-backtrace-limit=">,
>>>>>> > Group<f_Group>;
>>>>>> > +def foperatorarrow_depth_EQ : Joined<["-"],
>>>>>> "foperatorarrow-depth=">,
>>>>>> > Group<f_Group>;
>>>>>> > +def foperatorarrow_depth_ : Joined<["-"], "foperatorarrow-depth-">,
>>>>>> > Group<f_Group>;
>>>>>>
>>>>>
>>>>> Please remove this variant. We only support the - form for
>>>>> -ftemplate-depth for compatibility with an old g++ misstep.
>>>>>
>>>>>
>>>>>> > def ftest_coverage : Flag<["-"], "ftest-coverage">,
>>>>>> Group<f_Group>;
>>>>>> > def fvectorize : Flag<["-"], "fvectorize">, Group<f_Group>,
>>>>>> > HelpText<"Enable the loop vectorization passes">;
>>>>>> >
>>>>>> >
>>>>>> >
>>>>>> > Please if someone could help me by reviewing it and suggesting
>>>>>> improvements?
>>>>>>
>>>>>
>>>>> It looks basically right, other than the tweaks above. Thanks!
>>>>>
>>>>> Please also add this flag to the documentation.
>>>>>
>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131106/0ea160df/attachment.html>
More information about the cfe-commits
mailing list