Clang's static analyzer found several potential cases of undefined
behavior, use of un-initialized values, and potentially null pointer
dereferences in tablegen, Support, MC, and ADT. This cleans them up
with specific assertions on the assumptions of the code.
llvm-svn: 224154
Ideally we would store the MultiClasses by value directly in the maps, but I had some trouble with that before and this at least fixes the leak.
llvm-svn: 223997
Upon further review I think the MultiClass is being copied into the map instead of being moved due to the copy constructor on the nested Record type. This ultimately got exposed when the vector in DefPrototype vector was changed to hold unique_ptrs in another commit. This caused gcc 4.7 to fail due to the use of the copy constructor on unique_ptr with the error pointing back to one of the insert calls from this commit. Not sure why clang was able to build.
This reverts commit 710cdf729f84b428bf41aa8d32dbdb35fff79fde.
llvm-svn: 222971
The previous patch had effect, but missed this one. It seems MSVC
gets ADL-confused by the calls where the first argument is a function call?
llvm-svn: 222968
It was failing with this kind of error:
C:\b\build\slave\CrWinClang\build\src\third_party\llvm\lib\TableGen\TGParser.cpp(1243) : error C2668: 'llvm::make_unique' : ambiguous call to overloaded function
C:\b\build\slave\CrWinClang\build\src\third_party\llvm\include\llvm/ADT/STLExtras.h(408): could be 'std::unique_ptr<llvm::Record,std::default_delete<_Ty>> llvm::make_unique<llvm::Record,std::string,llvm::SMLoc&,llvm::RecordKeeper&,bool>(std::string &&,llvm::SMLoc &,llvm::RecordKeeper &,bool &&)'
with
[
_Ty=llvm::Record
]
C:\b\depot_tools\win_toolchain\vs2013_files\win8sdk\bin\..\..\VC\include\memory(1637): or 'std::unique_ptr<llvm::Record,std::default_delete<_Ty>> std::make_unique<llvm::Record,std::string,llvm::SMLoc&,llvm::RecordKeeper&,bool>(std::string &&,llvm::SMLoc &,llvm::RecordKeeper &,bool &&)' [found using argument-dependent lookup]
with
[
_Ty=llvm::Record
]
while trying to match the argument list '(std::string, llvm::SMLoc, llvm::RecordKeeper, bool)'
llvm-svn: 222967
By class-instance values I mean 'Class<Arg>' in 'Class<Arg>.Field' or in
'Other<Class<Arg>>' (syntactically s SimpleValue). This is to differentiate
from unnamed/anonymous record definitions (syntactically an ObjectBody) which
are not affected by this change.
Consider the testcase:
class Struct<int i> {
int I = !shl(i, 1);
int J = !shl(I, 1);
}
class Class<Struct s> {
int Class_J = s.J;
}
multiclass MultiClass<int i> {
def Def : Class<Struct<i>>;
}
defm Defm : MultiClass<2>;
Before this fix, DefmDef.Class_J yields !shl(I, 1) instead of 8.
This is the sequence of events. We start with this:
multiclass MultiClass<int i> {
def Def : Class<Struct<i>>;
}
During ParseDef the anonymous object for the class-instance value is created:
multiclass Multiclass<int i> {
def anonymous_0 : Struct<i>;
def Def : Class<NAME#anonymous_0>;
}
Then class Struct<i> is added to anonymous_0. Also Class<NAME#anonymous_0> is
added to Def:
multiclass Multiclass<int i> {
def anonymous_0 {
int I = !shl(i, 1);
int J = !shl(I, 1);
}
def Def {
int Class_J = NAME#anonymous_0.J;
}
}
So far so good but then we move on to instantiating this in the defm
by substituting the template arg 'i'.
This is how the anonymous prototype looks after fully instantiating.
defm Defm = {
def Defmanonymous_0 {
int I = 4;
int J = !shl(I, 1);
}
Note that we only resolved the reference to the template arg. The
non-template-arg reference in 'J' has not been resolved yet.
Then we go on to instantiating the Def prototype:
def DefmDef {
int Class_J = NAME#anonymous_0.J;
}
Which is resolved to Defmanonymous_0.J and then to !shl(I, 1).
When we fully resolve each record in a defm, Defmanonymous_0.J does get set
to 8 but that's too late for its use.
The patch adds a new attribute to the Record class that indicates that this
def is actually a class-instance value that may be *used* by other defs in a
multiclass. (This is unlike regular defs which don't reference each other and
thus can be resolved indepedently.) They are then fully resolved before the
other defs while the multiclass is instantiated.
I added vg_leak to the new test. I am not sure if this is necessary but I
don't think I have a way to test it. I can also check in without the XFAIL
and let the bots test this part.
Also tested that X86.td.expanded and AAarch64.td.expanded were unchange before
and after this change. (This issue triggering this problem is a WIP patch.)
Part of <rdar://problem/17688758>
llvm-svn: 217886
Take a StringRef instead of a "const char *".
Take a "std::error_code &" instead of a "std::string &" for error.
A create static method would be even better, but this patch is already a bit too
big.
llvm-svn: 216393
This does nothing but remove the Record from the map, and
then re-add it, without actually changing it in between.
The Record's Name used to be changed before re-adding it
when the code was first committed in r137232, but the
name-changing lines were removed in r142510, and since
then this code seems to do nothing.
This was also the only caller of removeClass or removeDef,
so now RecordKeeper owns its Records unconditionally,
and could be unique_ptr-ified.
llvm-svn: 216349
Add header guards to files that were missing guards. Remove #endif comments
as they don't seem common in LLVM (we can easily add them back if we decide
they're useful)
Changes made by clang-tidy with minor tweaks.
llvm-svn: 215558
It also allows nested { } expressions, as now that they are sized, we can merge pull bits from the nested value.
In the current behaviour, everything in { } must have been convertible to a single bit.
However, now that binary literals are sized, its useful to be able to initialize a range of bits.
So, for example, its now possible to do
bits<8> x = { 0, 1, { 0b1001 }, 0, 0b0 }
llvm-svn: 215086
Instead of these becoming an integer literal internally, they now become bits<n> values.
Prior to this change, 0b001 was 1 bit long. This is confusing as clearly the user gave 3 bits.
This new type holds both the literal value and the size, and so can ensure sizes match on initializers.
For example, this used to be legal
bits<1> x = 0b00;
but now it must be written as
bits<2> x = 0b00;
llvm-svn: 215084
Prior to this change, it was legal to do something like
bits<2> opc = { 0, 1 };
bits<2> opc2 = { 1, 0 };
bits<2> a = { opc, opc2 };
This involved silently dropping bits from opc and opc2 which is very hard to debug.
Now the above test would be an error. Having tested with an assert, none of LLVM/clang was relying on this behaviour.
Thanks to Adam Nemet for the above test.
llvm-svn: 215083
Instead allow the variable to be declared, but don't attach an initializer. This allows more than a single error to be emitted before we exit.
Test case to follow soon in another patch.
llvm-svn: 214375
This is currently for assigning from one bit init to another. It can easily be extended to other types.
Test to follow soon in another patch.
llvm-svn: 214374
Convert the operand to int if possible, i.e. if the value is properly
initialized. (I suppose there is further room for improvement here to also
peform the shift if the uninitialized bits are shifted out.)
With this little change we can now compute the scaling factor for compressed
displacement with pure tablegen code in the X86 backend. This is useful
because both the X86-disassembler-specific part of tablegen and the assembler
need this and TD is the natural sharing place.
The patch also adds the missing documentation for the shift and add operator.
llvm-svn: 213277
Use 0 for the invalid buffer instead of -1/~0 and switch to unsigned
representation to enable more idiomatic usage.
Also introduce a trivial SourceMgr::getMainFileID() instead of hard-coding 0/1
to identify the main file.
llvm-svn: 212398
string_ostream is a safe and efficient string builder that combines opaque
stack storage with a built-in ostream interface.
small_string_ostream<bytes> additionally permits an explicit stack storage size
other than the default 128 bytes to be provided. Beyond that, storage is
transferred to the heap.
This convenient class can be used in most places an
std::string+raw_string_ostream pair or SmallString<>+raw_svector_ostream pair
would previously have been used, in order to guarantee consistent access
without byte truncation.
The patch also converts much of LLVM to use the new facility. These changes
include several probable bug fixes for truncated output, a programming error
that's no longer possible with the new interface.
llvm-svn: 211749
Also removed an inaccurate comment that stated that a DenseMap was used as
storage for the ListInit*'s. It's currently using a FoldingSet.
I expect there's a better way to fix this but I haven't found it yet. FoldingSet
is incompatible with the Pool template and I'm not sure if FoldingSet can be
safely replaced with a DenseMap of computed FoldingSetID's to ListInit*'s.
llvm-svn: 208293