Skip to content

Commit be88539

Browse files
Replace llvm::isPodLike<...> by llvm::is_trivially_copyable<...>
As noted in https://bugs.llvm.org/show_bug.cgi?id=36651, the specialization for isPodLike<std::pair<...>> did not match the expectation of std::is_trivially_copyable which makes the memcpy optimization invalid. This patch renames the llvm::isPodLike trait into llvm::is_trivially_copyable. Unfortunately std::is_trivially_copyable is not portable across compiler / STL versions. So a portable version is provided too. Note that the following specialization were invalid: std::pair<T0, T1> llvm::Optional<T> Tests have been added to assert that former specialization are respected by the standard usage of llvm::is_trivially_copyable, and that when a decent version of std::is_trivially_copyable is available, llvm::is_trivially_copyable is compared to std::is_trivially_copyable. As of this patch, llvm::Optional is no longer considered trivially copyable, even if T is. This is to be fixed in a later patch, as it has impact on a long-running bug (see r347004) Note that GCC warns about this UB, but this got silented by https://reviews.llvm.org/D50296. Differential Revision: https://reviews.llvm.org/D54472 llvm-svn: 351701
1 parent 7ac79ed commit be88539

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+119
-212
lines changed

clang/include/clang/AST/BaseSubobject.h

-5
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,6 @@ template<> struct DenseMapInfo<clang::BaseSubobject> {
8080
}
8181
};
8282

83-
// It's OK to treat BaseSubobject as a POD type.
84-
template <> struct isPodLike<clang::BaseSubobject> {
85-
static const bool value = true;
86-
};
87-
8883
} // namespace llvm
8984

9085
#endif // LLVM_CLANG_AST_BASESUBOBJECT_H

clang/include/clang/AST/CharUnits.h

-4
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,6 @@ template<> struct DenseMapInfo<clang::CharUnits> {
237237
}
238238
};
239239

240-
template <> struct isPodLike<clang::CharUnits> {
241-
static const bool value = true;
242-
};
243-
244240
} // end namespace llvm
245241

246242
#endif // LLVM_CLANG_AST_CHARUNITS_H

clang/include/clang/AST/DeclAccessPair.h

-8
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,4 @@ class DeclAccessPair {
6060
};
6161
}
6262

63-
// Take a moment to tell SmallVector that DeclAccessPair is POD.
64-
namespace llvm {
65-
template<typename> struct isPodLike;
66-
template<> struct isPodLike<clang::DeclAccessPair> {
67-
static const bool value = true;
68-
};
69-
}
70-
7163
#endif

clang/include/clang/AST/DeclarationName.h

-3
Original file line numberDiff line numberDiff line change
@@ -861,9 +861,6 @@ struct DenseMapInfo<clang::DeclarationName> {
861861
}
862862
};
863863

864-
template <>
865-
struct isPodLike<clang::DeclarationName> { static const bool value = true; };
866-
867864
} // namespace llvm
868865

869866
#endif // LLVM_CLANG_AST_DECLARATIONNAME_H

clang/include/clang/AST/ExprObjC.h

-6
Original file line numberDiff line numberDiff line change
@@ -255,12 +255,6 @@ struct ObjCDictionaryElement {
255255

256256
} // namespace clang
257257

258-
namespace llvm {
259-
260-
template <> struct isPodLike<clang::ObjCDictionaryElement> : std::true_type {};
261-
262-
} // namespace llvm
263-
264258
namespace clang {
265259

266260
/// Internal struct for storing Key/value pair.

clang/include/clang/AST/GlobalDecl.h

-7
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,6 @@ namespace llvm {
139139
}
140140
};
141141

142-
// GlobalDecl isn't *technically* a POD type. However, its copy constructor,
143-
// copy assignment operator, and destructor are all trivial.
144-
template <>
145-
struct isPodLike<clang::GlobalDecl> {
146-
static const bool value = true;
147-
};
148-
149142
} // namespace llvm
150143

151144
#endif // LLVM_CLANG_AST_GLOBALDECL_H

clang/include/clang/AST/Type.h

-3
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,6 @@ namespace llvm {
9494
enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
9595
};
9696

97-
template <>
98-
struct isPodLike<clang::QualType> { static const bool value = true; };
99-
10097
} // namespace llvm
10198

10299
namespace clang {

clang/include/clang/Analysis/ProgramPoint.h

-3
Original file line numberDiff line numberDiff line change
@@ -777,9 +777,6 @@ static bool isEqual(const clang::ProgramPoint &L,
777777

778778
};
779779

780-
template <>
781-
struct isPodLike<clang::ProgramPoint> { static const bool value = true; };
782-
783780
} // end namespace llvm
784781

785782
#endif

clang/include/clang/Basic/IdentifierTable.h

-3
Original file line numberDiff line numberDiff line change
@@ -938,9 +938,6 @@ struct DenseMapInfo<clang::Selector> {
938938
}
939939
};
940940

941-
template <>
942-
struct isPodLike<clang::Selector> { static const bool value = true; };
943-
944941
template<>
945942
struct PointerLikeTypeTraits<clang::Selector> {
946943
static const void *getAsVoidPointer(clang::Selector P) {

clang/include/clang/Basic/SourceLocation.h

-6
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
namespace llvm {
2626

2727
template <typename T> struct DenseMapInfo;
28-
template <typename T> struct isPodLike;
2928

3029
} // namespace llvm
3130

@@ -457,11 +456,6 @@ namespace llvm {
457456
}
458457
};
459458

460-
template <>
461-
struct isPodLike<clang::SourceLocation> { static const bool value = true; };
462-
template <>
463-
struct isPodLike<clang::FileID> { static const bool value = true; };
464-
465459
// Teach SmallPtrSet how to handle SourceLocation.
466460
template<>
467461
struct PointerLikeTypeTraits<clang::SourceLocation> {

clang/include/clang/Lex/Token.h

-5
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,4 @@ struct PPConditionalInfo {
328328

329329
} // end namespace clang
330330

331-
namespace llvm {
332-
template <>
333-
struct isPodLike<clang::Token> { static const bool value = true; };
334-
} // end namespace llvm
335-
336331
#endif // LLVM_CLANG_LEX_TOKEN_H

clang/include/clang/Sema/CodeCompleteConsumer.h

-8
Original file line numberDiff line numberDiff line change
@@ -655,14 +655,6 @@ class CodeCompletionTUInfo {
655655

656656
} // namespace clang
657657

658-
namespace llvm {
659-
660-
template <> struct isPodLike<clang::CodeCompletionString::Chunk> {
661-
static const bool value = true;
662-
};
663-
664-
} // namespace llvm
665-
666658
namespace clang {
667659

668660
/// A builder class used to construct new code-completion strings.

clang/include/clang/Sema/Ownership.h

-3
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,6 @@ namespace llvm {
128128
}
129129
};
130130

131-
template <class T>
132-
struct isPodLike<clang::OpaquePtr<T>> { static const bool value = true; };
133-
134131
} // namespace llvm
135132

136133
namespace clang {

clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h

-9
Original file line numberDiff line numberDiff line change
@@ -667,13 +667,4 @@ class ConcreteInt : public Loc {
667667

668668
} // namespace clang
669669

670-
namespace llvm {
671-
672-
template <typename T> struct isPodLike;
673-
template <> struct isPodLike<clang::ento::SVal> {
674-
static const bool value = true;
675-
};
676-
677-
} // namespace llvm
678-
679670
#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H

clang/lib/AST/VTableBuilder.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,8 @@ class ItaniumVTableBuilder {
846846
: BaseOffset(CharUnits::Zero()),
847847
BaseOffsetInLayoutClass(CharUnits::Zero()),
848848
VTableIndex(0) { }
849+
850+
MethodInfo(MethodInfo const&) = default;
849851
};
850852

851853
typedef llvm::DenseMap<const CXXMethodDecl *, MethodInfo> MethodInfoMapTy;

clang/lib/Sema/SemaChecking.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -11662,12 +11662,12 @@ class SequenceChecker : public EvaluatedExprVisitor<SequenceChecker> {
1166211662
class Seq {
1166311663
friend class SequenceTree;
1166411664

11665-
unsigned Index = 0;
11665+
unsigned Index;
1166611666

1166711667
explicit Seq(unsigned N) : Index(N) {}
1166811668

1166911669
public:
11670-
Seq() = default;
11670+
Seq() : Index(0) {}
1167111671
};
1167211672

1167311673
SequenceTree() { Values.push_back(Value(0)); }

clang/lib/StaticAnalyzer/Core/RegionStore.cpp

-4
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,6 @@ namespace llvm {
130130
return os;
131131
}
132132

133-
template <typename T> struct isPodLike;
134-
template <> struct isPodLike<BindingKey> {
135-
static const bool value = true;
136-
};
137133
} // end llvm namespace
138134

139135
#ifndef NDEBUG

clang/test/Analysis/llvm-conventions.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,6 @@ inline bool operator>(StringRef LHS, StringRef RHS);
152152
inline bool operator>=(StringRef LHS, StringRef RHS);
153153
inline std::string &operator+=(std::string &buffer, StringRef string);
154154
hash_code hash_value(StringRef S);
155-
template <typename T> struct isPodLike;
156-
template <> struct isPodLike<StringRef> { static const bool value = true; };
157155

158156
} // end of namespace llvm
159157

clang/tools/libclang/Indexing.cpp

-3
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,6 @@ typedef llvm::DenseSet<PPRegion> PPRegionSetTy;
9393
} // end anonymous namespace
9494

9595
namespace llvm {
96-
template <> struct isPodLike<PPRegion> {
97-
static const bool value = true;
98-
};
9996

10097
template <>
10198
struct DenseMapInfo<PPRegion> {

llvm/docs/ProgrammersManual.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -1456,7 +1456,7 @@ SmallVector has grown a few other minor advantages over std::vector, causing
14561456
#. std::vector is exception-safe, and some implementations have pessimizations
14571457
that copy elements when SmallVector would move them.
14581458

1459-
#. SmallVector understands ``isPodLike<Type>`` and uses realloc aggressively.
1459+
#. SmallVector understands ``llvm::is_trivially_copyable<Type>`` and uses realloc aggressively.
14601460

14611461
#. Many LLVM APIs take a SmallVectorImpl as an out parameter (see the note
14621462
below).

llvm/include/llvm/ADT/ArrayRef.h

-6
Original file line numberDiff line numberDiff line change
@@ -525,12 +525,6 @@ namespace llvm {
525525

526526
/// @}
527527

528-
// ArrayRefs can be treated like a POD type.
529-
template <typename T> struct isPodLike;
530-
template <typename T> struct isPodLike<ArrayRef<T>> {
531-
static const bool value = true;
532-
};
533-
534528
template <typename T> hash_code hash_value(ArrayRef<T> S) {
535529
return hash_combine_range(S.begin(), S.end());
536530
}

llvm/include/llvm/ADT/DenseMap.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ class DenseMapBase : public DebugEpochBase {
145145
}
146146

147147
const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
148-
if (isPodLike<KeyT>::value && isPodLike<ValueT>::value) {
148+
if (is_trivially_copyable<KeyT>::value &&
149+
is_trivially_copyable<ValueT>::value) {
149150
// Use a simpler loop when these are trivial types.
150151
for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P)
151152
P->getFirst() = EmptyKey;
@@ -421,7 +422,8 @@ class DenseMapBase : public DebugEpochBase {
421422
setNumEntries(other.getNumEntries());
422423
setNumTombstones(other.getNumTombstones());
423424

424-
if (isPodLike<KeyT>::value && isPodLike<ValueT>::value)
425+
if (is_trivially_copyable<KeyT>::value &&
426+
is_trivially_copyable<ValueT>::value)
425427
memcpy(reinterpret_cast<void *>(getBuckets()), other.getBuckets(),
426428
getNumBuckets() * sizeof(BucketT));
427429
else

llvm/include/llvm/ADT/ImmutableList.h

-4
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,6 @@ template<typename T> struct DenseMapInfo<ImmutableList<T>> {
241241
}
242242
};
243243

244-
template <typename T> struct isPodLike;
245-
template <typename T>
246-
struct isPodLike<ImmutableList<T>> { static const bool value = true; };
247-
248244
} // end namespace llvm
249245

250246
#endif // LLVM_ADT_IMMUTABLELIST_H

llvm/include/llvm/ADT/Optional.h

+1-6
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class raw_ostream;
3030

3131
namespace optional_detail {
3232
/// Storage for any type.
33-
template <typename T, bool = isPodLike<T>::value> struct OptionalStorage {
33+
template <typename T, bool = is_trivially_copyable<T>::value> struct OptionalStorage {
3434
AlignedCharArrayUnion<T> storage;
3535
bool hasVal = false;
3636

@@ -185,11 +185,6 @@ template <typename T> class Optional {
185185
#endif
186186
};
187187

188-
template <typename T> struct isPodLike<Optional<T>> {
189-
// An Optional<T> is pod-like if T is.
190-
static const bool value = isPodLike<T>::value;
191-
};
192-
193188
template <typename T, typename U>
194189
bool operator==(const Optional<T> &X, const Optional<U> &Y) {
195190
if (X && Y)

llvm/include/llvm/ADT/PointerIntPair.h

-6
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,6 @@ struct PointerIntPairInfo {
175175
}
176176
};
177177

178-
template <typename T> struct isPodLike;
179-
template <typename PointerTy, unsigned IntBits, typename IntType>
180-
struct isPodLike<PointerIntPair<PointerTy, IntBits, IntType>> {
181-
static const bool value = true;
182-
};
183-
184178
// Provide specialization of DenseMapInfo for PointerIntPair.
185179
template <typename PointerTy, unsigned IntBits, typename IntType>
186180
struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType>> {

llvm/include/llvm/ADT/SmallVector.h

+7-8
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,9 @@ class SmallVectorTemplateCommon : public SmallVectorBase {
179179
}
180180
};
181181

182-
/// SmallVectorTemplateBase<isPodLike = false> - This is where we put method
182+
/// SmallVectorTemplateBase<TriviallyCopyable = false> - This is where we put method
183183
/// implementations that are designed to work with non-POD-like T's.
184-
template <typename T, bool = isPodLike<T>::value>
184+
template <typename T, bool = is_trivially_copyable<T>::value>
185185
class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
186186
protected:
187187
SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
@@ -235,8 +235,8 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
235235
};
236236

237237
// Define this out-of-line to dissuade the C++ compiler from inlining it.
238-
template <typename T, bool isPodLike>
239-
void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
238+
template <typename T, bool TriviallyCopyable>
239+
void SmallVectorTemplateBase<T, TriviallyCopyable>::grow(size_t MinSize) {
240240
if (MinSize > UINT32_MAX)
241241
report_bad_alloc_error("SmallVector capacity overflow during allocation");
242242

@@ -259,9 +259,8 @@ void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
259259
this->Capacity = NewCapacity;
260260
}
261261

262-
263-
/// SmallVectorTemplateBase<isPodLike = true> - This is where we put method
264-
/// implementations that are designed to work with POD-like T's.
262+
/// SmallVectorTemplateBase<TriviallyCopyable = true> - This is where we put
263+
/// method implementations that are designed to work with POD-like T's.
265264
template <typename T>
266265
class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> {
267266
protected:
@@ -330,7 +329,7 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T> {
330329
protected:
331330
// Default ctor - Initialize to empty.
332331
explicit SmallVectorImpl(unsigned N)
333-
: SmallVectorTemplateBase<T, isPodLike<T>::value>(N) {}
332+
: SmallVectorTemplateBase<T>(N) {}
334333

335334
public:
336335
SmallVectorImpl(const SmallVectorImpl &) = delete;

llvm/include/llvm/ADT/StringRef.h

-4
Original file line numberDiff line numberDiff line change
@@ -927,10 +927,6 @@ namespace llvm {
927927
LLVM_NODISCARD
928928
hash_code hash_value(StringRef S);
929929

930-
// StringRefs can be treated like a POD type.
931-
template <typename T> struct isPodLike;
932-
template <> struct isPodLike<StringRef> { static const bool value = true; };
933-
934930
} // end namespace llvm
935931

936932
#endif // LLVM_ADT_STRINGREF_H

llvm/include/llvm/ADT/bit.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ template <typename To, typename From
4040
, typename = typename std::enable_if<__is_trivially_copyable(To)>::type
4141
, typename = typename std::enable_if<__is_trivially_copyable(From)>::type
4242
#else
43-
// This case is GCC 4.x. clang with libc++ or libstdc++ never get here. Unlike
44-
// llvm/Support/type_traits.h's isPodLike we don't want to provide a
45-
// good-enough answer here: developers in that configuration will hit
46-
// compilation failures on the bots instead of locally. That's acceptable
47-
// because it's very few developers, and only until we move past C++11.
43+
// This case is GCC 4.x. clang with libc++ or libstdc++ never get here. Unlike
44+
// llvm/Support/type_traits.h's is_trivially_copyable we don't want to
45+
// provide a good-enough answer here: developers in that configuration will hit
46+
// compilation failures on the bots instead of locally. That's acceptable
47+
// because it's very few developers, and only until we move past C++11.
4848
#endif
4949
>
5050
inline To bit_cast(const From &from) noexcept {

0 commit comments

Comments
 (0)