Commit Graph

4172 Commits

Author SHA1 Message Date
Reid Kleckner c8ae878399 [MS] Make sure __GetExceptionInfo works on types with no linkage
Fixes PR36327

llvm-svn: 335175
2018-06-20 21:12:20 +00:00
Alex Lorenz 1f79297ebe Recommit r335063: [Darwin] Add a warning for missing include path for libstdc++
The recommit ensures that the tests that failed on bots don't trigger the warning.

Xcode 10 removes support for libstdc++, but the users just get a confusing
include not file warning when including an STL header (when building for iOS6
which uses libstdc++ by default for example).
This patch adds a new warning that lets the user know that the libstdc++ include
path was not found to ensure that the user is more aware of why the error occurs.

rdar://40830462

Differential Revision: https://reviews.llvm.org/D48297

llvm-svn: 335081
2018-06-19 22:47:53 +00:00
Taiju Tsuiki 3be68e162f Revert r335019 "Update NRVO logic to support early return (Attempt 2)"
llvm-svn: 335022
2018-06-19 05:35:30 +00:00
Taiju Tsuiki b000a8860e Update NRVO logic to support early return (Attempt 2)
Summary:
This is the second attempt of r333500 (Update NRVO logic to support early return).
The previous one was reverted for a miscompilation for an incorrect NRVO set up on templates such as:
```
struct Foo {};

template <typename T>
T bar() {
  T t;
  if (false)
    return T();
  return t;
}
```

Where, `t` is marked as non-NRVO variable before its instantiation. However, while its instantiation, it's left an NRVO candidate, turned into an NRVO variable later.

Reviewers: rsmith

Reviewed By: rsmith

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D47586

llvm-svn: 335019
2018-06-19 04:39:07 +00:00
Peter Collingbourne d914fd2163 IRgen: Mark aliases of ctors and dtors as unnamed_addr.
This is not only semantically correct but ensures that they will not
be marked as address-significant once D48155 lands.

Differential Revision: https://reviews.llvm.org/D48206

llvm-svn: 334982
2018-06-18 20:58:54 +00:00
Yaxun Liu a505635fdb Add RUN line for amdgcn to lit test conditional-temporaries.cpp
This is partial re-commit of r332982.

llvm-svn: 334886
2018-06-16 12:28:51 +00:00
Piotr Padlewski e368de364e Add -fforce-emit-vtables
Summary:
 In many cases we can't devirtualize
 because definition of vtable is not present. Most of the
 time it is caused by inline virtual function not beeing
 emitted. Forcing emitting of vtable adds a reference of these
 inline virtual functions.
 Note that GCC was always doing it.

Reviewers: rjmccall, rsmith, amharc, kuhar

Subscribers: llvm-commits, cfe-commits

Differential Revision: https://reviews.llvm.org/D47108

Co-authored-by: Krzysztof Pszeniczny <krzysztof.pszeniczny@gmail.com>
llvm-svn: 334600
2018-06-13 13:55:42 +00:00
Richard Smith 8fa638ae6f Fix crash emitting transparent list initializer for a large aggregate.
llvm-svn: 334565
2018-06-13 02:06:28 +00:00
Hans Wennborg 4cae35f6e4 [MS ABI] Mangle unnamed empty enums (PR37723)
Differential Revision: https://reviews.llvm.org/D47875

llvm-svn: 334388
2018-06-11 06:54:23 +00:00
Shoaib Meenai d8d1547387 [Frontend] Disallow non-MSVC exception models for windows-msvc targets
The windows-msvc target is used for MSVC ABI compatibility, including
the exceptions model. It doesn't make sense to pair a windows-msvc
target with a non-MSVC exception model. This would previously cause an
assertion failure; explicitly error out for it in the frontend instead.
This also allows us to reduce the matrix of target/exception models a
bit (see the modified tests), and we can possibly simplify some of the
personality code in a follow-up.

Differential Revision: https://reviews.llvm.org/D47853

llvm-svn: 334243
2018-06-07 22:54:54 +00:00
Reid Kleckner 89fbd55145 Revert r333791 "Cap "voluntary" vector alignment at 16 for all Darwin platforms."
Adding __attribute__((aligned(32))) to __m256 breaks the implementation
of _mm256_loadu_ps on Windows. On Windows, alignment attributes have
higher precedence than packing attributes.

We also might want to carefully consider the consequences of changing
our vector typedefs, since many users copy them and invent their own
new, non-Intel specific vector type names.

llvm-svn: 333958
2018-06-04 21:39:20 +00:00
John McCall 280c656031 Cap "voluntary" vector alignment at 16 for all Darwin platforms.
This fixes two major problems:
- We were not capping vector alignment as desired on 32-bit ARM.
- We were using different alignments based on the AVX settings on
  Intel, so we did not have a consistent ABI.

This is an ABI break, but we think we can get away with it because
vectors tend to be used mostly in inline code (which is why not having
a consistent ABI has not proven disastrous on Intel).

Intel's AVX types are specified as having 32-byte / 64-byte alignment,
so align them explicitly instead of relying on the base ABI rule.
Note that this sort of attribute is stripped from template arguments
in template substitution, so there's a possibility that code templated
over vectors will produce inadequately-aligned objects.  The right
long-term solution for this is for alignment attributes to be
interpreted as true qualifiers and thus preserved in the canonical type.

llvm-svn: 333791
2018-06-01 21:34:26 +00:00
Heejin Ahn 1eb074d76e [WebAssembly] Hide new Wasm EH behind its feature flag
Summary:
clang's current wasm EH implementation is a non-MVP feature in progress.
We had a `-mexception-handling` wasm feature but were not using it. This
patch hides the non-MVP wasm EH behind a flag, so it does not affect
other code for now.

Reviewers: dschuff

Subscribers: sbc100, jgravelle-google, sunfish, cfe-commits

Differential Revision: https://reviews.llvm.org/D47614

llvm-svn: 333716
2018-06-01 01:01:37 +00:00
Heejin Ahn c647919933 [WebAssembly] Use Windows EH instructions for Wasm EH
Summary:
Because wasm control flow needs to be structured, using WinEH
instructions to support wasm EH brings several benefits. This patch
makes wasm EH uses Windows EH instructions, with some changes:
1. Because wasm uses a single catch block to catch all C++ exceptions,
   this merges all catch clauses into a single catchpad, within which we
   test the EH selector as in Itanium EH.
2. Generates a call to `__clang_call_terminate` in case a cleanup
   throws. Wasm does not have a runtime to handle this.
3. In case there is no catch-all clause, inserts a call to
   `__cxa_rethrow` at the end of a catchpad in order to unwind to an
   enclosing EH scope.

Reviewers: majnemer, dschuff

Subscribers: jfb, sbc100, jgravelle-google, sunfish, cfe-commits

Differential Revision: https://reviews.llvm.org/D44931

llvm-svn: 333703
2018-05-31 22:18:13 +00:00
Reid Kleckner 26fc531dbc Fix null MSInheritanceAttr deref in CXXRecordDecl::getMSInheritanceModel()
Ensure latest MPT decl has a MSInheritanceAttr when instantiating
templates, to avoid null MSInheritanceAttr deref in
CXXRecordDecl::getMSInheritanceModel().

See PR#37399 for repo / details.

Patch by Andrew Rogers!

Differential Revision: https://reviews.llvm.org/D46664

llvm-svn: 333680
2018-05-31 18:42:29 +00:00
Sam McCall 5429bd751c Revert "Update NRVO logic to support early return"
This reverts commit r333500, which causes stage2 compiler crashes.

llvm-svn: 333547
2018-05-30 14:14:58 +00:00
Taiju Tsuiki 44f9c585b9 Update NRVO logic to support early return
Summary:
The previous implementation misses an opportunity to apply NRVO (Named Return Value
Optimization) below. That discourages user to write early return code.

```
struct Foo {};

Foo f(bool b) {
  if (b)
    return Foo();
  Foo oo;
  return oo;
}
```
That is, we can/should apply RVO for a local variable if:
 * It's directly returned by at least one return statement.
 * And, all reachable return statements in its scope returns the variable directly.
While, the previous implementation disables the RVO in a scope if there are multiple return
statements that refers different variables.

On the new algorithm, local variables are in NRVO_Candidate state at first, and a return
statement changes it to NRVO_Disabled for all visible variables but the return statement refers.
Then, at the end of the function AST traversal, NRVO is enabled for variables in NRVO_Candidate
state and refers from at least one return statement.

Reviewers: rsmith

Reviewed By: rsmith

Subscribers: xbolva00, Quuxplusone, arthur.j.odwyer, cfe-commits

Differential Revision: https://reviews.llvm.org/D47067

llvm-svn: 333500
2018-05-30 03:53:16 +00:00
Richard Smith b534510cd5 Make the mangled name collision diagnostic a bit more useful by listing the mangling.
This helps especially when the collision is for a template specialization,
where the template arguments are not available from anywhere else in the
diagnostic, and are likely relevant to the problem.

llvm-svn: 333489
2018-05-30 01:52:16 +00:00
Richard Smith 6ca999baf2 Revert r332839.
This is causing miscompiles and "definition with same mangled name as another
definition" errors.

llvm-svn: 333482
2018-05-30 00:45:10 +00:00
Akira Hatanaka 1da9dbbc25 [CodeGen][Darwin] Set the calling-convention of thread-local variable
initialization functions to 'cxx_fast_tlscc'.

This fixes a bug where instructions calling initialization functions for
thread-local static members of c++ template classes were using calling
convention 'cxx_fast_tlscc' while the called functions weren't annotated
with the calling convention.

rdar://problem/40447463

Differential Revision: https://reviews.llvm.org/D47354

llvm-svn: 333447
2018-05-29 18:28:49 +00:00
Richard Smith 3e268632cf Use zeroinitializer for (trailing zero portion of) large array initializers
more reliably.

This re-commits r333044 with a fix for PR37560.

llvm-svn: 333141
2018-05-23 23:41:38 +00:00
Hans Wennborg 156349fa10 Revert r333044 "Use zeroinitializer for (trailing zero portion of) large array initializers"
It caused asserts, see PR37560.

> Use zeroinitializer for (trailing zero portion of) large array initializers
> more reliably.
>
> Clang has two different ways it emits array constants (from InitListExprs and
> from APValues), and both had some ability to emit zeroinitializer, but neither
> was able to catch all cases where we could use zeroinitializer reliably. In
> particular, emitting from an APValue would fail to notice if all the explicit
> array elements happened to be zero. In addition, for large arrays where only an
> initial portion has an explicit initializer, we would emit the complete
> initializer (which could be huge) rather than emitting only the non-zero
> portion. With this change, when the element would have a suffix of more than 8
> zero elements, we emit the array constant as a packed struct of its initial
> portion followed by a zeroinitializer constant for the trailing zero portion.
>
> In passing, I found a bug where SemaInit would sometimes walk the entire array
> when checking an initializer that only covers the first few elements; that's
> fixed here to unblock testing of the rest.
>
> Differential Revision: https://reviews.llvm.org/D47166

llvm-svn: 333067
2018-05-23 08:24:01 +00:00
Richard Smith 9062bbf419 Use zeroinitializer for (trailing zero portion of) large array initializers
more reliably.

Clang has two different ways it emits array constants (from InitListExprs and
from APValues), and both had some ability to emit zeroinitializer, but neither
was able to catch all cases where we could use zeroinitializer reliably. In
particular, emitting from an APValue would fail to notice if all the explicit
array elements happened to be zero. In addition, for large arrays where only an
initial portion has an explicit initializer, we would emit the complete
initializer (which could be huge) rather than emitting only the non-zero
portion. With this change, when the element would have a suffix of more than 8
zero elements, we emit the array constant as a packed struct of its initial
portion followed by a zeroinitializer constant for the trailing zero portion.

In passing, I found a bug where SemaInit would sometimes walk the entire array
when checking an initializer that only covers the first few elements; that's
fixed here to unblock testing of the rest.

Differential Revision: https://reviews.llvm.org/D47166

llvm-svn: 333044
2018-05-23 00:09:29 +00:00
Yaxun Liu 00ddbed298 Revert r332982 Call CreateTempMemWithoutCast for ActiveFlag
Due to regression on arm.

llvm-svn: 332991
2018-05-22 16:13:07 +00:00
Yaxun Liu 8a60e5db70 Call CreateTempMemWithoutCast for ActiveFlag
Introduced CreateMemTempWithoutCast and CreateTemporaryAllocaWithoutCast to emit alloca
without casting to default addr space.

ActiveFlag is a temporary variable emitted for clean up. It is defined as AllocaInst* type and there is
a cast to AlllocaInst in SetActiveFlag. An alloca casted to generic pointer causes assertion in
SetActiveFlag.

Since there is only load/store of ActiveFlag, it is safe to use the original alloca, therefore use
CreateMemTempWithoutCast is called.

Differential Revision: https://reviews.llvm.org/D47099

llvm-svn: 332982
2018-05-22 14:36:26 +00:00
Brock Wyma 8557ec5d64 [CodeView] Enable debugging of captured variables within C++ lambdas
This change will help Visual Studio resolve forward references to C++ lambda
routines used by captured variables.

Differential Revision: https://reviews.llvm.org/D45438

llvm-svn: 332975
2018-05-22 12:41:19 +00:00
Richard Smith 3f1d6de4f7 Revert r332847; it caused us to miscompile certain forms of reference initialization.
llvm-svn: 332886
2018-05-21 20:36:58 +00:00
Richard Smith bbb2655de0 Revert r332028; see PR37545 for details.
llvm-svn: 332879
2018-05-21 20:10:54 +00:00
Serge Pavlov 9f8068420a [CodeGen] Recognize more cases of zero initialization
If a variable has an initializer, codegen tries to build its value. If
the variable is large in size, building its value requires substantial
resources. It causes strange behavior from user viewpoint: compilation
of huge zero initialized arrays like:

    char data_1[2147483648u] = { 0 };

consumes enormous amount of time and memory.

With this change codegen tries to determine if variable initializer is
equivalent to zero initializer. In this case variable value is not
constructed.

This change fixes PR18978.

Differential Revision: https://reviews.llvm.org/D46241

llvm-svn: 332847
2018-05-21 16:09:54 +00:00
Pavel Labath b3b0255df9 [CodeGen] Disable aggressive structor optimizations at -O0, take 2
The first version of the patch (r332228) was flawed because it was
putting structors into C5/D5 comdats very eagerly. This is correct only
if we can ensure the comdat contains all required versions of the
structor (which wasn't the case). This version uses a more nuanced
approach:
- for local structor symbols we use an alias because we don't have to
  worry about comdats or other compilation units.
- linkonce symbols are emitted separately, as we cannot guarantee we
  will have all symbols we need to form a comdat (they are emitted
  lazily, only when referenced).
- available_externally symbols are also emitted separately, as the code
  seemed to be worried about emitting an alias in this case.
- other linkage types are not affected by the optimization level. They
  either get put into a comdat (weak) or get aliased (external).

Reviewers: rjmccall, aprantl

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D46685

llvm-svn: 332839
2018-05-21 11:47:45 +00:00
JF Bastien 6b23972f07 CodeGen: block capture shouldn't ICE
When a lambda capture captures a __block in the same statement, the compiler asserts out because isCapturedBy assumes that an Expr can only be a BlockExpr, StmtExpr, or if it's a Stmt then all the statement's children are expressions. That's wrong, we need to visit all sub-statements even if they're not expressions to see if they also capture.

Fix this issue by pulling out the isCapturedBy logic to use RecursiveASTVisitor.

<rdar://problem/39926584>

llvm-svn: 332801
2018-05-19 04:21:26 +00:00
Douglas Yung d40bc5f788 Maintain PS4 ABI compatibility by making the fix made in r331136 not apply when the target is the PS4.
Reviewers: rsmith

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D47084

llvm-svn: 332773
2018-05-18 21:51:46 +00:00
Richard Smith fb50dd34ed Revert r332470 (and corresponding tests in r332492).
This regressed our support for __attribute__((section)). See added test file
for example of code broken by this.

llvm-svn: 332760
2018-05-18 20:18:17 +00:00
Reid Kleckner e9128f8405 Add missing test case for r332639
llvm-svn: 332646
2018-05-17 18:34:05 +00:00
Yaxun Liu a2a9cfab83 CodeGen: Fix invalid bitcast for lifetime.start/end
lifetime.start/end expects pointer argument in alloca address space.
However in C++ a temporary variable is in default address space.

This patch changes API CreateMemTemp and CreateTempAlloca to
get the original alloca instruction and pass it lifetime.start/end.

It only affects targets with non-zero alloca address space.

Differential Revision: https://reviews.llvm.org/D45900

llvm-svn: 332593
2018-05-17 11:16:35 +00:00
Erich Keane a3c0c9a2ba Add lit tests forgotten for R332470
I forgot to svn-add the lit tests for R332470.  
Added here!

llvm-svn: 332492
2018-05-16 17:04:47 +00:00
Douglas Yung 9a40ff502f Revert commits r332160, r332164, r332236.
It was decided this is the wrong approach to fix this issue.

llvm-svn: 332421
2018-05-16 00:27:43 +00:00
Brock Wyma 3db2b108c3 [CodeView] Improve debugging of virtual base class member variables
Initial support for passing the virtual base pointer offset to CodeViewDebug.

https://reviews.llvm.org/D46271

llvm-svn: 332296
2018-05-14 21:21:22 +00:00
Yaxun Liu daceb1ea0f CodeGen: Emit string literal in constant address space
Some targets have constant address space (e.g. amdgcn). For them string literal should be
emitted in constant address space then casted to default address space.

Differential Revision: https://reviews.llvm.org/D46643

llvm-svn: 332279
2018-05-14 19:20:12 +00:00
Pavel Labath c370f26251 Revert "[CodeGen] Disable aggressive structor optimizations at -O0"
It breaks the sanitizer build
<http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-autoconf/builds/23739>

This reverts commit r332228.

llvm-svn: 332232
2018-05-14 11:35:44 +00:00
Pavel Labath f639eb0553 [CodeGen] Disable aggressive structor optimizations at -O0
Summary:
Removing the full structor and replacing all usages with the base one
can degrade debug quality as it will leave the debugger unable to locate
the full object structor. This is apparent when evaluating an expression
in the debugger which requires constructing an object of class which has
had this optimization applied to it.  When compiling the expression, we
pretend that the class and its methods have been defined in another
compilation unit, so the expression compiler assumes the structor
definition must be available. This didn't use to be the case for
structors with internal linkage. Less aggressive optimizations like
emitting the full structor as an alias remain in place, as they do not
cause the structor symbol to disappear completely.

This improves debug quality on non-darwin platforms (darwin does not
have -mconstructor-aliases on by default, so it is spared these
problems) and enable us to remove some workarounds from LLDB which attempt to
mitigate this issue.

Reviewers: rjmccall, aprantl

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D46685

llvm-svn: 332228
2018-05-14 11:02:23 +00:00
Douglas Yung dde9de7cf9 Force the PS4 clang ABI version to 6.
The PS4 requires clang ABI version 6 for compatibility reasons. This change forces this and if the user specifies a different version when the PS4 target is specified, the compiler emits a warning that the specified version is being ignored.

Reviewers: probinson

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D46767

llvm-svn: 332160
2018-05-12 00:06:59 +00:00
Reid Kleckner df6dbf6719 Don't propagate dllimport to base class template static data members
MSVC doesn't, so we shouldn't. Fixes PR37232.

llvm-svn: 332074
2018-05-11 01:26:11 +00:00
Eric Fiselier 85ba3321c6 [Itanium] Emit type info names with external linkage.
Summary:
The Itanium ABI requires that the type info for pointer-to-incomplete types to have internal linkage, so that it doesn't interfere with the type info once completed.  Currently it also marks the type info name as internal as well. However, this causes a bug with the STL implementations, which use the type info name pointer to perform ordering and hashing of type infos.
For example:

```
// header.h
struct T;
extern std::type_info const& Info;

// tu_one.cpp
#include "header.h"
std::type_info const& Info = typeid(T*);

// tu_two.cpp
#include "header.h"
struct T {};
int main() {
  auto &TI1 = Info;
  auto &TI2 = typeid(T*);
  assert(TI1 == TI2); // Fails
  assert(TI1.hash_code() == TI2.hash_code()); // Fails
}
```

This patch fixes the STL bug by emitting the type info name as linkonce_odr when the type-info is for a pointer-to-incomplete type.

Note that libc++ could fix this without a compiler change, but the quality of fix would be poor. The library would either have to:

(A) Always perform strcmp/string hashes.
(B) Determine if we have a pointer-to-incomplete type, and only do strcmp then. This would require an ABI break for libc++.


Reviewers: rsmith, rjmccall, majnemer, vsapsai

Reviewed By: rjmccall

Subscribers: smeenai, cfe-commits

Differential Revision: https://reviews.llvm.org/D46665

llvm-svn: 332028
2018-05-10 19:51:56 +00:00
Strahinja Petrovic 0f274c0111 This patch provides that bitfields are splitted even in case
when current field is not legal integer type.

Differential Revision: https://reviews.llvm.org/D39053

llvm-svn: 331979
2018-05-10 12:31:12 +00:00
Eric Fiselier 864ef70eb0 Revert "[Itanium] Emit type info names with external linkage."
This reverts commit r331957. It seems to be causing failures
on ppc64le-linux.

llvm-svn: 331963
2018-05-10 08:10:57 +00:00
Eric Fiselier ae56a957af [Itanium] Emit type info names with external linkage.
Summary:
The Itanium ABI requires that the type info for pointer-to-incomplete types to have internal linkage, so that it doesn't interfere with the type info once completed.  Currently it also marks the type info name as internal as well. However, this causes a bug with the STL implementations, which use the type info name pointer to perform ordering and hashing of type infos.
For example:

```
// header.h
struct T;
extern std::type_info const& Info;

// tu_one.cpp
#include "header.h"
std::type_info const& Info = typeid(T*);

// tu_two.cpp
#include "header.h"
struct T {};
int main() {
  auto &TI1 = Info;
  auto &TI2 = typeid(T*);
  assert(TI1 == TI2); // Fails
  assert(TI1.hash_code() == TI2.hash_code()); // Fails
}
```

This patch fixes the STL bug by emitting the type info name as linkonce_odr when the type-info is for a pointer-to-incomplete type.

Note that libc++ could fix this without a compiler change, but the quality of fix would be poor. The library would either have to:

(A) Always perform strcmp/string hashes.
(B) Determine if we have a pointer-to-incomplete type, and only do strcmp then. This would require an ABI break for libc++.


Reviewers: rsmith, rjmccall, majnemer, vsapsai

Reviewed By: rjmccall

Subscribers: smeenai, cfe-commits

Differential Revision: https://reviews.llvm.org/D46665

llvm-svn: 331957
2018-05-10 05:25:15 +00:00
Eric Fiselier 98a1cab694 [C++2a] Implement operator<=>: Fix another bug in the code gen tests.
Sorry for the failures. I'm quite new at writing code gen tests, and
I'm not sure the best way to make them portable.

llvm-svn: 331745
2018-05-08 07:56:05 +00:00
Eric Fiselier 2ab957e67b Fix failing codegen test on non-x86_64 platforms
llvm-svn: 331697
2018-05-07 23:15:34 +00:00
Eric Fiselier 0683c0e68d [C++2a] Implement operator<=> CodeGen and ExprConstant
Summary:
This patch tackles long hanging fruit for the builtin operator<=> expressions. It is currently needs some cleanup before landing, but I want to get some initial feedback.

The main changes are:

* Lookup, build, and store the required standard library types and expressions in `ASTContext`. By storing them in ASTContext we don't need to store (and duplicate) the required expressions in the BinaryOperator AST nodes. 

* Implement [expr.spaceship] checking, including diagnosing narrowing conversions. 

* Implement `ExprConstant` for builtin spaceship operators.

* Implement builitin operator<=> support in `CodeGenAgg`. Initially I emitted the required comparisons using `ScalarExprEmitter::VisitBinaryOperator`, but this caused the operand expressions to be emitted once for every required cmp.

* Implement [builtin.over] with modifications to support the intent of P0946R0. See the note on `BuiltinOperatorOverloadBuilder::addThreeWayArithmeticOverloads` for more information about the workaround.




Reviewers: rsmith, aaron.ballman, majnemer, rnk, compnerd, rjmccall

Reviewed By: rjmccall

Subscribers: rjmccall, rsmith, aaron.ballman, junbuml, mgorny, cfe-commits

Differential Revision: https://reviews.llvm.org/D45476

llvm-svn: 331677
2018-05-07 21:07:10 +00:00