Endless operator-> chain causing infinite loop
Rahul Jain
1989.rahuljain at gmail.com
Fri Oct 25 07:45:55 PDT 2013
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");
+ 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;
+ 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();
+ }
- 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;
+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")
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>;
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?
Thanks,
Rahul
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131025/e78c3408/attachment.html>
More information about the cfe-commits
mailing list