summaryrefslogtreecommitdiff
path: root/lib/Sema/Sema.cpp
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@apple.com>2019-07-13 01:47:15 +0000
committerAkira Hatanaka <ahatanaka@apple.com>2019-07-13 01:47:15 +0000
commit657b099cc209b4c70658e8cbc1e29e40b7dbffe7 (patch)
tree1c79967bb90719a1d22e9b8ee2b957570bc15364 /lib/Sema/Sema.cpp
parentdd578bb497322855a0116d2ed3b6ccff7f8ad7db (diff)
downloadclang-657b099cc209b4c70658e8cbc1e29e40b7dbffe7.tar.gz
[Sema] Diagnose default-initialization, destruction, and copying of
non-trivial C union types This patch diagnoses uses of non-trivial C unions and structs/unions containing non-trivial C unions in the following contexts, which require default-initialization, destruction, or copying of the union objects, instead of disallowing fields of non-trivial types in C unions, which is what we currently do: - function parameters. - function returns. - assignments. - compound literals. - block captures except capturing of `__block` variables by non-escaping blocks. - local and global variable definitions. - lvalue-to-rvalue conversions of volatile types. See the discussion in https://reviews.llvm.org/D62988 for more background. rdar://problem/50679094 Differential Revision: https://reviews.llvm.org/D63753 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@365985 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/Sema.cpp')
-rw-r--r--lib/Sema/Sema.cpp18
1 files changed, 15 insertions, 3 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 3941643893..11fed28b52 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -1658,12 +1658,24 @@ static void markEscapingByrefs(const FunctionScopeInfo &FSI, Sema &S) {
// Set the EscapingByref flag of __block variables captured by
// escaping blocks.
for (const BlockDecl *BD : FSI.Blocks) {
- if (BD->doesNotEscape())
- continue;
for (const BlockDecl::Capture &BC : BD->captures()) {
VarDecl *VD = BC.getVariable();
- if (VD->hasAttr<BlocksAttr>())
+ if (VD->hasAttr<BlocksAttr>()) {
+ // Nothing to do if this is a __block variable captured by a
+ // non-escaping block.
+ if (BD->doesNotEscape())
+ continue;
VD->setEscapingByref();
+ }
+ // Check whether the captured variable is or contains an object of
+ // non-trivial C union type.
+ QualType CapType = BC.getVariable()->getType();
+ if (CapType.hasNonTrivialToPrimitiveDestructCUnion() ||
+ CapType.hasNonTrivialToPrimitiveCopyCUnion())
+ S.checkNonTrivialCUnion(BC.getVariable()->getType(),
+ BD->getCaretLocation(),
+ Sema::NTCUC_BlockCapture,
+ Sema::NTCUK_Destruct|Sema::NTCUK_Copy);
}
}