Bug Summary

File:jdk/src/hotspot/share/adlc/forms.hpp
Warning:line 286, column 22
Although the value stored to 'cur' is used in the enclosing expression, the value is never actually read from 'cur'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name filebuff.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mthread-model posix -mframe-pointer=all -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -D LINUX -D ASSERT -D AMD64 -I /home/daniel/Projects/java/jdk/src/hotspot/share -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-unused-parameter -Wno-unused -fdeprecated-macro -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make/hotspot -ferror-limit 19 -fmessage-length 0 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c++ /home/daniel/Projects/java/jdk/src/hotspot/share/adlc/filebuff.cpp
1/*
2 * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#ifndef SHARE_ADLC_FORMS_HPP
26#define SHARE_ADLC_FORMS_HPP
27
28// FORMS.HPP - ADL Parser Generic and Utility Forms Classes
29
30#define TRUE1 1
31#define FALSE0 0
32
33// DEFINITIONS OF LEGAL ATTRIBUTE TYPES
34#define INS_ATTR0 0
35#define OP_ATTR1 1
36
37// DEFINITIONS OF LEGAL CONSTRAINT TYPES
38
39// Class List
40class Form;
41class InstructForm;
42class MachNodeForm;
43class OperandForm;
44class OpClassForm;
45class AttributeForm;
46class RegisterForm;
47class PipelineForm;
48class SourceForm;
49class EncodeForm;
50class Component;
51class Constraint;
52class Predicate;
53class MatchRule;
54class Attribute;
55class Effect;
56class ExpandRule;
57class RewriteRule;
58class ConstructRule;
59class FormatRule;
60class Peephole;
61class EncClass;
62class Interface;
63class RegInterface;
64class ConstInterface;
65class MemInterface;
66class CondInterface;
67class Opcode;
68class InsEncode;
69class RegDef;
70class RegClass;
71class CodeSnippetRegClass;
72class ConditionalRegClass;
73class AllocClass;
74class ResourceForm;
75class PipeClassForm;
76class PeepMatch;
77class PeepConstraint;
78class PeepReplace;
79class MatchList;
80
81class ArchDesc;
82
83//------------------------------FormDict---------------------------------------
84// Dictionary containing Forms, and objects derived from forms
85class FormDict {
86private:
87 Dict _form; // map names, char*, to their Form* or NULL
88
89 // Disable public use of constructor, copy-ctor, operator =, operator ==
90 FormDict( );
91 FormDict &operator =( const FormDict & );
92 // == compares two dictionaries; they must have the same keys (their keys
93 // must match using CmpKey) and they must have the same values (pointer
94 // comparison). If so 1 is returned, if not 0 is returned.
95 bool operator ==(const FormDict &d) const; // Compare dictionaries for equal
96
97public:
98 // cmp is a key comparision routine. hash is a routine to hash a key.
99 // FormDict( CmpKey cmp, Hash hash );
100 FormDict( CmpKey cmp, Hash hash, Arena *arena );
101 FormDict( const FormDict & fd ); // Deep-copy guts
102 ~FormDict();
103
104 // Return # of key-value pairs in dict
105 int Size(void) const;
106
107 // Insert inserts the given key-value pair into the dictionary. The prior
108 // value of the key is returned; NULL if the key was not previously defined.
109 const Form *Insert(const char *name, Form *form); // A new key-value
110
111 // Find finds the value of a given key; or NULL if not found.
112 // The dictionary is NOT changed.
113 const Form *operator [](const char *name) const; // Do a lookup
114
115 void dump();
116};
117
118// ***** Master Class for ADL Parser Forms *****
119//------------------------------Form-------------------------------------------
120class Form {
121public:
122 static Arena *arena; // arena used by forms
123private:
124 static Arena *generate_arena(); // allocate arena used by forms
125
126protected:
127 int _ftype; // Indicator for derived class type
128
129public:
130 // Public Data
131 Form *_next; // Next pointer for form lists
132 int _linenum; // Line number for debugging
133
134 // Dynamic type check for common forms.
135 virtual OpClassForm *is_opclass() const;
136 virtual OperandForm *is_operand() const;
137 virtual InstructForm *is_instruction() const;
138 virtual MachNodeForm *is_machnode() const;
139 virtual AttributeForm *is_attribute() const;
140 virtual Effect *is_effect() const;
141 virtual ResourceForm *is_resource() const;
142 virtual PipeClassForm *is_pipeclass() const;
143
144 // Check if this form is an operand usable for cisc-spilling
145 virtual bool is_cisc_reg(FormDict &globals) const { return false; }
146 virtual bool is_cisc_mem(FormDict &globals) const { return false; }
147
148 // Public Methods
149 Form(int formType=0, int line=0)
150 : _next(NULL__null), _linenum(line), _ftype(formType) { };
151 virtual ~Form() {};
152
153 virtual bool ideal_only() const {
154 assert(0,"Check of ideal status on non-instruction/operand form.\n"){ if (!(0)) { fprintf(stderr, "assert fails %s %d: %s\n", "/home/daniel/Projects/java/jdk/src/hotspot/share/adlc/forms.hpp"
, 154, "Check of ideal status on non-instruction/operand form.\n"
); abort(); }}
;
155 return FALSE0;
156 }
157
158 // Check constraints after parsing
159 virtual bool verify() { return true; }
160
161 virtual void dump() { output(stderrstderr); } // Debug printer
162 // Write info to output files
163 virtual void output(FILE *fp) { fprintf(fp,"Form Output"); }
164
165public:
166 // ADLC types, match the last character on ideal operands and instructions
167 enum DataType {
168 none = 0, // Not a simple type
169 idealI = 1, // Integer type
170 idealP = 2, // Pointer types, oop(s)
171 idealL = 3, // Long type
172 idealF = 4, // Float type
173 idealD = 5, // Double type
174 idealB = 6, // Byte type
175 idealC = 7, // Char type
176 idealS = 8, // String type
177 idealN = 9, // Narrow oop types
178 idealNKlass = 10, // Narrow klass types
179 idealV = 11 // Vector type
180 };
181 // Convert ideal name to a DataType, return DataType::none if not a 'ConX'
182 Form::DataType ideal_to_const_type(const char *ideal_type_name) const;
183 // Convert ideal name to a DataType, return DataType::none if not a 'sRegX
184 Form::DataType ideal_to_sReg_type(const char *name) const;
185 // Convert ideal name to a DataType, return DataType::none if not a 'RegX
186 Form::DataType ideal_to_Reg_type(const char *name) const;
187
188 // Convert ideal name to a DataType, return DataType::none if not a 'LoadX
189 Form::DataType is_load_from_memory(const char *opType) const;
190 // Convert ideal name to a DataType, return DataType::none if not a 'StoreX
191 Form::DataType is_store_to_memory(const char *opType) const;
192
193 // ADLC call types, matched with ideal world
194 enum CallType {
195 invalid_type = 0, // invalid call type
196 JAVA_STATIC = 1, // monomorphic entry
197 JAVA_DYNAMIC = 2, // possibly megamorphic, inline cache call
198 JAVA_COMPILED = 3, // callee will be compiled java
199 JAVA_INTERP = 4, // callee will be executed by interpreter
200 JAVA_NATIVE = 5, // native entrypoint
201 JAVA_RUNTIME = 6, // runtime entrypoint
202 JAVA_LEAF = 7 // calling leaf
203 };
204
205 // Interface types for operands and operand classes
206 enum InterfaceType {
207 no_interface = 0, // unknown or inconsistent interface type
208 constant_interface = 1, // interface to constants
209 register_interface = 2, // interface to registers
210 memory_interface = 3, // interface to memory
211 conditional_interface = 4 // interface for condition codes
212 };
213 virtual Form::InterfaceType interface_type(FormDict &globals) const;
214
215 enum CiscSpillInfo {
216 Not_cisc_spillable = AdlcVMDeps::Not_cisc_spillable,
217 Maybe_cisc_spillable = 0,
218 Is_cisc_spillable = 1
219 // ...
220 };
221
222 // LEGAL FORM TYPES
223 enum {
224 INS,
225 OPER,
226 OPCLASS,
227 SRC,
228 ADEF,
229 REG,
230 PIPE,
231 CNST,
232 PRED,
233 ATTR,
234 MAT,
235 ENC,
236 FOR,
237 EXP,
238 REW,
239 EFF,
240 RDEF,
241 RCL,
242 ACL,
243 RES,
244 PCL,
245 PDEF,
246 REGL,
247 RESL,
248 STAL,
249 COMP,
250 PEEP,
251 RESO
252 };
253
254};
255
256//------------------------------FormList---------------------------------------
257class FormList {
258private:
259 Form *_root;
260 Form *_tail;
261 Form *_cur;
262 int _justReset; // Set immediately after reset
263 Form *_cur2; // Nested iterator
264 int _justReset2;
265
266public:
267 void addForm(Form * entry) {
268 if (_tail==NULL__null) { _root = _tail = _cur = entry;}
269 else { _tail->_next = entry; _tail = entry;}
270 };
271 Form * current() { return _cur; };
272 Form * iter() { if (_justReset) _justReset = 0;
273 else if (_cur) _cur = _cur->_next;
274 return _cur;};
275 void reset() { if (_root) {_cur = _root; _justReset = 1;} };
276
277 // Second iterator, state is internal
278 Form * current2(){ return _cur2; };
279 Form * iter2() { if (_justReset2) _justReset2 = 0;
280 else if (_cur2) _cur2 = _cur2->_next;
281 return _cur2;};
282 void reset2() { if (_root) {_cur2 = _root; _justReset2 = 1;} };
283
284 int count() {
285 int count = 0; reset();
286 for( Form *cur; (cur = iter()) != NULL__null; ) { ++count; };
Although the value stored to 'cur' is used in the enclosing expression, the value is never actually read from 'cur'
287 return count;
288 }
289
290 void dump() {
291 reset();
292 Form *cur;
293 for(; (cur = iter()) != NULL__null; ) {
294 cur->dump();
295 };
296 }
297
298 bool verify() {
299 bool verified = true;
300
301 reset();
302 Form *cur;
303 for(; (cur = iter()) != NULL__null; ) {
304 if ( ! cur->verify() ) verified = false;
305 };
306
307 return verified;
308 }
309
310 void output(FILE* fp) {
311 reset();
312 Form *cur;
313 for( ; (cur = iter()) != NULL__null; ) {
314 cur->output(fp);
315 };
316 }
317
318 FormList() { _justReset = 1; _justReset2 = 1; _root = NULL__null; _tail = NULL__null; _cur = NULL__null; _cur2 = NULL__null;};
319 ~FormList();
320};
321
322//------------------------------NameList---------------------------------------
323// Extendable list of pointers, <char *>
324class NameList {
325 friend class PreserveIter;
326
327private:
328 int _cur; // Insert next entry here; count of entries
329 int _max; // Number of spaces allocated
330 const char **_names; // Array of names
331
332protected:
333 int _iter; // position during iteration
334 bool _justReset; // Set immediately after reset
335
336
337public:
338 static const char *_signal; // reserved user-defined string
339 static const char *_signal2; // reserved user-defined string
340 static const char *_signal3; // reserved user-defined string
341 enum { Not_in_list = -1 };
342
343 void addName(const char *name);
344 void add_signal();
345 void clear(); // Remove all entries
346
347 int count() const;
348
349 void reset(); // Reset iteration
350 const char *iter(); // after reset(), first element : else next
351 const char *current(); // return current element in iteration.
352 const char *peek(int skip = 1); // returns element + skip in iteration if there is one
353
354 bool current_is_signal(); // Return 'true' if current entry is signal
355 bool is_signal(const char *entry); // Return true if entry is a signal
356
357 bool search(const char *); // Search for a name in the list
358 int index(const char *); // Return index of name in list
359 const char *name (intptr_t index);// Return name at index in list
360
361 void dump(); // output to stderr
362 void output(FILE *fp); // Output list of names to 'fp'
363
364 NameList();
365 ~NameList();
366};
367
368
369// Convenience class to preserve iteration state since iterators are
370// internal instead of being external.
371class PreserveIter {
372 private:
373 NameList* _list;
374 int _iter;
375 bool _justReset;
376
377 public:
378 PreserveIter(NameList* nl) {
379 _list = nl;
380 _iter = _list->_iter;
381 _justReset = _list->_justReset;
382 }
383 ~PreserveIter() {
384 _list->_iter = _iter;
385 _list->_justReset = _justReset;
386 }
387
388};
389
390
391//------------------------------NameAndList------------------------------------
392// Storage for a name and an associated list of names
393class NameAndList {
394private:
395 const char *_name;
396 NameList _list;
397
398public:
399 NameAndList(char *name);
400 ~NameAndList();
401
402 // Add to entries in list
403 void add_entry(const char *entry);
404
405 // Access the name and its associated list.
406 const char *name() const;
407 void reset();
408 const char *iter();
409
410 int count() { return _list.count(); }
411
412 // Return the "index" entry in the list, zero-based
413 const char *operator[](int index);
414
415
416 void dump(); // output to stderr
417 void output(FILE *fp); // Output list of names to 'fp'
418};
419
420//------------------------------ComponentList---------------------------------
421// Component lists always have match rule operands first, followed by parameter
422// operands which do not appear in the match list (in order of declaration).
423class ComponentList : private NameList {
424private:
425 int _matchcnt; // Count of match rule operands
426
427public:
428
429 // This is a batch program. (And I have a destructor bug!)
430 void operator delete( void *ptr ) {}
431
432 void insert(Component *component, bool mflag);
433 void insert(const char *name, const char *opType, int usedef, bool mflag);
434
435 int count();
436 int match_count() { return _matchcnt; } // Get count of match rule opers
437
438 Component *iter(); // after reset(), first element : else next
439 Component *match_iter(); // after reset(), first element : else next
440 Component *post_match_iter(); // after reset(), first element : else next
441 void reset(); // Reset iteration
442 Component *current(); // return current element in iteration.
443
444 // Return element at "position", else NULL
445 Component *operator[](int position);
446 Component *at(int position) { return (*this)[position]; }
447
448 // Return first component having this name.
449 const Component *search(const char *name);
450
451 // Return number of USEs + number of DEFs
452 int num_operands();
453 // Return zero-based position in list; -1 if not in list.
454 int operand_position(const char *name, int usedef, Form *fm);
455 // Find position for this name, regardless of use/def information
456 int operand_position(const char *name);
457 // Find position for this name when looked up for output via "format"
458 int operand_position_format(const char *name, Form *fm);
459 // Find position for the Label when looked up for output via "format"
460 int label_position();
461 // Find position for the Method when looked up for output via "format"
462 int method_position();
463
464 void dump(); // output to stderr
465 void output(FILE *fp); // Output list of names to 'fp'
466
467 ComponentList();
468 ~ComponentList();
469};
470
471//------------------------------SourceForm-------------------------------------
472class SourceForm : public Form {
473private:
474
475public:
476 // Public Data
477 char *_code; // Buffer for storing code text
478
479 // Public Methods
480 SourceForm(char* code);
481 ~SourceForm();
482
483 virtual const char* classname() { return "SourceForm"; }
484
485 void dump(); // Debug printer
486 void output(FILE *fp); // Write output files
487};
488
489class HeaderForm : public SourceForm {
490public:
491 HeaderForm(char* code) : SourceForm(code) { }
492
493 virtual const char* classname() { return "HeaderForm"; }
494};
495
496class PreHeaderForm : public SourceForm {
497public:
498 PreHeaderForm(char* code) : SourceForm(code) { }
499
500 virtual const char* classname() { return "PreHeaderForm"; }
501};
502
503
504
505
506//------------------------------Expr------------------------------------------
507#define STRING_BUFFER_LENGTH2048 2048
508// class Expr represents integer expressions containing constants and addition
509// Value must be in range zero through maximum positive integer. 32bits.
510// Expected use: instruction and operand costs
511class Expr {
512public:
513 enum {
514 Zero = 0,
515 Max = 0x7fffffff
516 };
517 const char *_external_name; // if !NULL, then print this instead of _expr
518 const char *_expr;
519 int _min_value;
520 int _max_value;
521
522 Expr();
523 Expr(const char *cost);
524 Expr(const char *name, const char *expression, int min_value, int max_value);
525 Expr *clone() const;
526
527 bool is_unknown() const { return (this == Expr::get_unknown()); }
528 bool is_zero() const { return (_min_value == Expr::Zero && _max_value == Expr::Zero); }
529 bool less_than_or_equal(const Expr *c) const { return (_max_value <= c->_min_value); }
530
531 void add(const Expr *c);
532 void add(const char *c);
533 void add(const char *c, ArchDesc &AD); // check if 'c' is defined in <arch>.ad
534 void set_external_name(const char *name) { _external_name = name; }
535
536 const char *as_string() const { return (_external_name != NULL__null ? _external_name : _expr); }
537 void print() const;
538 void print_define(FILE *fp) const;
539 void print_assert(FILE *fp) const;
540
541 static Expr *get_unknown(); // Returns pointer to shared unknown cost instance
542
543 static char *buffer() { return &external_buffer[0]; }
544 static bool init_buffers(); // Fill buffers with 0
545 static bool check_buffers(); // if buffer use may have overflowed, assert
546
547private:
548 static Expr *_unknown_expr;
549 static char string_buffer[STRING_BUFFER_LENGTH2048];
550 static char external_buffer[STRING_BUFFER_LENGTH2048];
551 static bool _init_buffers;
552 const char *compute_expr(const Expr *c1, const Expr *c2); // cost as string after adding 'c1' and 'c2'
553 int compute_min (const Expr *c1, const Expr *c2); // minimum after adding 'c1' and 'c2'
554 int compute_max (const Expr *c1, const Expr *c2); // maximum after adding 'c1' and 'c2'
555 const char *compute_external(const Expr *c1, const Expr *c2); // external name after adding 'c1' and 'c2'
556};
557
558//------------------------------ExprDict---------------------------------------
559// Dictionary containing Exprs
560class ExprDict {
561private:
562 Dict _expr; // map names, char*, to their Expr* or NULL
563 NameList _defines; // record the order of definitions entered with define call
564
565 // Disable public use of constructor, copy-ctor, operator =, operator ==
566 ExprDict( );
567 ExprDict( const ExprDict & ); // Deep-copy guts
568 ExprDict &operator =( const ExprDict & );
569 // == compares two dictionaries; they must have the same keys (their keys
570 // must match using CmpKey) and they must have the same values (pointer
571 // comparison). If so 1 is returned, if not 0 is returned.
572 bool operator ==(const ExprDict &d) const; // Compare dictionaries for equal
573
574public:
575 // cmp is a key comparision routine. hash is a routine to hash a key.
576 ExprDict( CmpKey cmp, Hash hash, Arena *arena );
577 ~ExprDict();
578
579 // Return # of key-value pairs in dict
580 int Size(void) const;
581
582 // define inserts the given key-value pair into the dictionary,
583 // and records the name in order for later output, ...
584 const Expr *define(const char *name, Expr *expr);
585
586 // Insert inserts the given key-value pair into the dictionary. The prior
587 // value of the key is returned; NULL if the key was not previously defined.
588 const Expr *Insert(const char *name, Expr *expr); // A new key-value
589
590 // Find finds the value of a given key; or NULL if not found.
591 // The dictionary is NOT changed.
592 const Expr *operator [](const char *name) const; // Do a lookup
593
594 void print_defines(FILE *fp);
595 void print_asserts(FILE *fp);
596 void dump();
597};
598
599#endif // SHARE_ADLC_FORMS_HPP