@@ -70,22 +70,31 @@ class OSLogFormatStringHandler
7070 bool HandlePrintfSpecifier (const analyze_printf::PrintfSpecifier &FS,
7171 const char *StartSpecifier, unsigned SpecifierLen,
7272 const TargetInfo &) override {
73+ // Set the argument expression. Arguments of struct/class/complex types are
74+ // ignored.
75+ auto CheckAndSetArgExpr = [&](unsigned Idx, auto &ArgE) {
76+ const Expr *E = Args[Idx];
77+ if (E && (E->getType ()->isRecordType () || E->getType ()->isComplexType ()))
78+ return false ;
79+ ArgE = E;
80+ return true ;
81+ };
82+
7383 if (!FS.consumesDataArgument () &&
7484 FS.getConversionSpecifier ().getKind () !=
7585 clang::analyze_format_string::ConversionSpecifier::PrintErrno)
7686 return true ;
7787
78- ArgsData. emplace_back () ;
88+ ArgData ArgD ;
7989 unsigned ArgIndex = FS.getArgIndex ();
8090 if (ArgIndex < Args.size ())
81- ArgsData.back ().E = Args[ArgIndex];
91+ if (!CheckAndSetArgExpr (ArgIndex, ArgD.E ))
92+ return true ;
8293
8394 // First get the Kind
84- ArgsData.back ().Kind = getKind (FS.getConversionSpecifier ().getKind ());
85- if (ArgsData.back ().Kind != OSLogBufferItem::ErrnoKind &&
86- !ArgsData.back ().E ) {
95+ ArgD.Kind = getKind (FS.getConversionSpecifier ().getKind ());
96+ if (ArgD.Kind != OSLogBufferItem::ErrnoKind && !ArgD.E ) {
8797 // missing argument
88- ArgsData.pop_back ();
8998 return false ;
9099 }
91100
@@ -97,10 +106,11 @@ class OSLogFormatStringHandler
97106 case clang::analyze_format_string::OptionalAmount::NotSpecified: // "%s"
98107 break ;
99108 case clang::analyze_format_string::OptionalAmount::Constant: // "%.16s"
100- ArgsData. back () .Size = precision.getConstantAmount ();
109+ ArgD .Size = precision.getConstantAmount ();
101110 break ;
102111 case clang::analyze_format_string::OptionalAmount::Arg: // "%.*s"
103- ArgsData.back ().Count = Args[precision.getArgIndex ()];
112+ if (!CheckAndSetArgExpr (precision.getArgIndex (), ArgD.Count ))
113+ return true ;
104114 break ;
105115 case clang::analyze_format_string::OptionalAmount::Invalid:
106116 return false ;
@@ -113,10 +123,11 @@ class OSLogFormatStringHandler
113123 case clang::analyze_format_string::OptionalAmount::NotSpecified: // "%P"
114124 return false ; // length must be supplied with pointer format specifier
115125 case clang::analyze_format_string::OptionalAmount::Constant: // "%.16P"
116- ArgsData. back () .Size = precision.getConstantAmount ();
126+ ArgD .Size = precision.getConstantAmount ();
117127 break ;
118128 case clang::analyze_format_string::OptionalAmount::Arg: // "%.*P"
119- ArgsData.back ().Count = Args[precision.getArgIndex ()];
129+ if (!CheckAndSetArgExpr (precision.getArgIndex (), ArgD.Count ))
130+ return true ;
120131 break ;
121132 case clang::analyze_format_string::OptionalAmount::Invalid:
122133 return false ;
@@ -125,22 +136,27 @@ class OSLogFormatStringHandler
125136 }
126137 default :
127138 if (FS.getPrecision ().hasDataArgument ()) {
128- ArgsData.back ().Precision = Args[FS.getPrecision ().getArgIndex ()];
139+ if (!CheckAndSetArgExpr (FS.getPrecision ().getArgIndex (),
140+ ArgD.Precision ))
141+ return true ;
129142 }
130143 break ;
131144 }
132145 if (FS.getFieldWidth ().hasDataArgument ()) {
133- ArgsData.back ().FieldWidth = Args[FS.getFieldWidth ().getArgIndex ()];
146+ if (!CheckAndSetArgExpr (FS.getFieldWidth ().getArgIndex (),
147+ ArgD.FieldWidth ))
148+ return true ;
134149 }
135150
136151 if (FS.isSensitive ())
137- ArgsData. back () .Flags |= OSLogBufferItem::IsSensitive;
152+ ArgD .Flags |= OSLogBufferItem::IsSensitive;
138153 else if (FS.isPrivate ())
139- ArgsData. back () .Flags |= OSLogBufferItem::IsPrivate;
154+ ArgD .Flags |= OSLogBufferItem::IsPrivate;
140155 else if (FS.isPublic ())
141- ArgsData. back () .Flags |= OSLogBufferItem::IsPublic;
156+ ArgD .Flags |= OSLogBufferItem::IsPublic;
142157
143- ArgsData.back ().MaskType = FS.getMaskType ();
158+ ArgD.MaskType = FS.getMaskType ();
159+ ArgsData.push_back (ArgD);
144160 return true ;
145161 }
146162
0 commit comments