1342 Commits

Author SHA1 Message Date
Rajveer Singh Bharadwaj
e12a1f8b32
[clang] Fix crash when inheriting from a cv-qualified type (#70594)
This change makes the `assertion` less strict in `debug` builds by
stripping qualifiers from the base class and ignoring them. I hope
`weakened` assertions don't affect other cases where such `errors` are
intended to be `caught` by the compiler.

Fixes #35603
Fixes #85256
2024-04-02 12:06:56 -04:00
Chris B
9434c08347
[HLSL] Implement array temporary support (#79382)
HLSL constant sized array function parameters do not decay to pointers.
Instead constant sized array types are preserved as unique types for
overload resolution, template instantiation and name mangling.

This implements the change by adding a new `ArrayParameterType` which
represents a non-decaying `ConstantArrayType`. The new type behaves the
same as `ConstantArrayType` except that it does not decay to a pointer.

Values of `ConstantArrayType` in HLSL decay during overload resolution
via a new `HLSLArrayRValue` cast to `ArrayParameterType`.

`ArrayParamterType` values are passed indirectly by-value to functions
in IR generation resulting in callee generated memcpy instructions.

The behavior of HLSL function calls is documented in the [draft language
specification](https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf)
under the Expr.Post.Call heading.

Additionally the design of this implementation approach is documented in
[Clang's
documentation](https://clang.llvm.org/docs/HLSL/FunctionCalls.html)

Resolves #70123
2024-04-01 12:10:10 -05:00
OverMighty
cf73f136c5
[clang][ExprConst] Fix second arg of __builtin_{clzg,ctzg} not always being evaluated (#86742)
Even if we don't actually use the value of the second argument, we have to evaluate it for side-effects.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-03-29 14:01:19 -07:00
OverMighty
ac1af75051
[clang] Implement constexpr support for __builtin_{clzg,ctzg} (#86577)
Fixes #86549.
2024-03-26 13:22:47 -07:00
Chris B
28ddbd4a86
[NFC] Refactor ConstantArrayType size storage (#85716)
In PR #79382, I need to add a new type that derives from
ConstantArrayType. This means that ConstantArrayType can no longer use
`llvm::TrailingObjects` to store the trailing optional Expr*.

This change refactors ConstantArrayType to store a 60-bit integer and
4-bits for the integer size in bytes. This replaces the APInt field
previously in the type but preserves enough information to recreate it
where needed.

To reduce the number of places where the APInt is re-constructed I've
also added some helper methods to the ConstantArrayType to allow some
common use cases that operate on either the stored small integer or the
APInt as appropriate.

Resolves #85124.
2024-03-26 14:15:56 -05:00
Timm Baeder
4294841ebc
[clang][ExprConst] Can't be past an invalid LValue designator (#84293)
For the test case in C, both `LV.getLValueOffset()` and
`Ctx.getTypeSizeInChars(Ty)` are zero, so we return `true` from
`isOnePastTheEndOfCompleteObject()` and ultimately diagnose this as
being one past the end, but the diagnostic doesn't make sense.
2024-03-18 14:56:16 +01:00
sethp
192be3c9c1
fix: constexpr bit_cast with empty base classes (#82383)
Prior to this commit, clang would fail to produce a constant value for
`b` in:

```c++
struct base {
};

struct s : base {
    int z;
};

constexpr auto b = std::bit_cast<s>(0x12); 
```

e.g. https://godbolt.org/z/srrbTMPq4
2024-03-17 17:35:13 +01:00
Sirraide
74d1a40915
[Clang] Ignore assumptions with side effects at compile time (#85534)
Fixes #85519.
2024-03-16 16:05:50 +01:00
Timm Bäder
c42bc2ea8f [clang][NFC] Make some local pointers const
The function returns a const Expr* anyway.
2024-03-15 09:57:27 +01:00
Sirraide
bd77a26e9a
[Clang][Sema] Properly get captured 'this' pointer in lambdas with an explicit object parameter in constant evaluator (#81102)
There were some bugs wrt explicit object parameters in lambdas in the
constant evaluator:
- The code evaluating a `CXXThisExpr` wasn’t checking for explicit
object parameters at all and thus assumed that there was no `this` in
the current context because the lambda didn’t have one, even though we
were in a member function and had captured its `this`.
- The code retrieving captures as lvalues *did* account for explicit
object parameters, but it did not handle the case of the explicit object
parameter being passed by value rather than by reference.

This fixes #80997.

---------

Co-authored-by: cor3ntin <corentinjabot@gmail.com>
Co-authored-by: Aaron Ballman <aaron@aaronballman.com>
2024-03-13 18:49:44 +01:00
Sirraide
2b5f68a5f6
[Clang][C++23] Implement P1774R8: Portable assumptions (#81014)
This implements the C++23 `[[assume]]` attribute.

Assumption information is lowered to a call to `@llvm.assume`, unless the expression has side-effects, in which case it is discarded and a warning is issued to tell the user that the assumption doesn’t do anything. A failed assumption at compile time is an error (unless we are in `MSVCCompat` mode, in which case we don’t check assumptions at compile time).

Due to performance regressions in LLVM, assumptions can be disabled with the `-fno-assumptions` flag. With it, assumptions will still be parsed and checked, but no calls to `@llvm.assume` will be emitted and assumptions will not be checked at compile time.
2024-03-09 12:07:16 +01:00
OverMighty
487cfbe494
[Clang] Implement constexpr support for __builtin_popcountg (#84318) 2024-03-08 01:01:37 +01:00
Mariya Podchishchaeva
aced81c0a5
[C23] Implement N3018: The constexpr specifier for object definitions (#73099)
The implementation mostly reuses C++ code paths where possible,
including narrowing check in order to provide diagnostic messages in
case initializer for constexpr variable is not exactly representable in
target type.

The following won't work due to lack of support for other features:
- Diagnosing of underspecified declarations involving constexpr
- Constexpr attached to compound literals

Also due to lack of support for char8_t some of examples with utf-8
strings don't work properly.

Fixes https://github.com/llvm/llvm-project/issues/64742
2024-03-06 09:46:35 +01:00
Atousa Duprat
c00c901f1c
[clang] Use separator for large numeric values in overflow diagnostic (#80939)
Add functionality to APInt::toString() that allows it to insert
separators between groups of digits, using the C++ literal
separator ' between groups.

Fixes issue #58228

Reviewers:  @AaronBallman, @cjdb, @tbaederr
2024-03-05 07:38:42 -05:00
Chris B
5c57fd717d
[HLSL] Vector standard conversions (#71098)
HLSL supports vector truncation and element conversions as part of
standard conversion sequences. The vector truncation conversion is a C++
second conversion in the conversion sequence. If a vector truncation is
in a conversion sequence an element conversion may occur after it before
the standard C++ third conversion.

Vector element conversions can be boolean conversions, floating point or
integral conversions or promotions.

[HLSL Draft
Specification](https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf)

---------

Co-authored-by: Aaron Ballman <aaron@aaronballman.com>
2024-02-15 14:58:06 -06:00
Bryce Wilson
f209352669
[clang] Allow builtin addc/subc to be constant evaluated (#81656)
[clang] Allow builtin addc/subc to be constant evaluated
2024-02-15 09:41:19 -06:00
Vlad Serebrennikov
b985d4179a [clang][NFC] Annotate ExprConstant.cpp with preferred_type
This helps debuggers to display values in bit-fields in a more helpful way.
2024-02-11 14:59:33 +03:00
Timm Bäder
d63c8bee58 [clang][ExprConst] Remove unnecessary cast
FD is a FunctionDecl, so no need to cast a FunctionDecl to a
CXXMethodDecl just to assign it to a FunctionDecl.
2024-02-08 15:30:24 +01:00
PiJoules
42357df2df
[clang] Add zero-initialization for fixed point types (#80781) 2024-02-06 15:57:15 -08:00
Tianlan Zhou
ee01a2c399
[clang] static operators should evaluate object argument (reland) (#80108)
This re-applies 30155fc0 with a fix for clangd.

### Description

clang don't evaluate the object argument of `static operator()` and
`static operator[]` currently, for example:

```cpp
#include <iostream>

struct Foo {
    static int operator()(int x, int y) {
        std::cout << "Foo::operator()" << std::endl;
        return x + y;
    }
    static int operator[](int x, int y) {
        std::cout << "Foo::operator[]" << std::endl;
        return x + y;
    }
};
Foo getFoo() {
    std::cout << "getFoo()" << std::endl;
    return {};
}
int main() {
    std::cout << getFoo()(1, 2) << std::endl;
    std::cout << getFoo()[1, 2] << std::endl;
}
```

`getFoo()` is expected to be called, but clang don't call it currently
(17.0.6). This PR fixes this issue.

Fixes #67976, reland #68485.

### Walkthrough

- **clang/lib/Sema/SemaOverload.cpp**
- **`Sema::CreateOverloadedArraySubscriptExpr` &
`Sema::BuildCallToObjectOfClassType`**
Previously clang generate `CallExpr` for static operators, ignoring the
object argument. In this PR `CXXOperatorCallExpr` is generated for
static operators instead, with the object argument as the first
argument.
  - **`TryObjectArgumentInitialization`**
`const` / `volatile` objects are allowed for static methods, so that we
can call static operators on them.
- **clang/lib/CodeGen/CGExpr.cpp**
  - **`CodeGenFunction::EmitCall`**
CodeGen changes for `CXXOperatorCallExpr` with static operators: emit
and ignore the object argument first, then emit the operator call.
- **clang/lib/AST/ExprConstant.cpp**
  - **`‎ExprEvaluatorBase::handleCallExpr‎`**
Evaluation of static operators in constexpr also need some small changes
to work, so that the arguments won't be out of position.
- **clang/lib/Sema/SemaChecking.cpp**
  - **`Sema::CheckFunctionCall`**
Code for argument checking also need to be modify, or it will fail the
test `clang/test/SemaCXX/overloaded-operator-decl.cpp`.
- **clang-tools-extra/clangd/InlayHints.cpp**
  - **`InlayHintVisitor::VisitCallExpr`**
Now that the `CXXOperatorCallExpr` for static operators also have object
argument, we should also take care of this situation in clangd.

### Tests

- **Added:**
    - **clang/test/AST/ast-dump-static-operators.cpp**
      Verify the AST generated for static operators.
    - **clang/test/SemaCXX/cxx2b-static-operator.cpp**
Static operators should be able to be called on const / volatile
objects.
- **Modified:**
    - **clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp**
    - **clang/test/CodeGenCXX/cxx2b-static-subscript-operator.cpp**
      Matching the new CodeGen.

### Documentation

- **clang/docs/ReleaseNotes.rst**
  Update release notes.

---------

Co-authored-by: Shafik Yaghmour <shafik@users.noreply.github.com>
Co-authored-by: cor3ntin <corentinjabot@gmail.com>
Co-authored-by: Aaron Ballman <aaron@aaronballman.com>
2024-01-31 15:27:06 +08:00
Aaron Ballman
201eb2b577 Revert "[clang] static operators should evaluate object argument (#68485)"
This reverts commit 30155fc0ef4fbdce2d79434aaae8d58b2fabb20a.

It seems to have broken some tests in clangd:
http://45.33.8.238/linux/129484/step_9.txt
2024-01-30 13:38:18 -05:00
Tianlan Zhou
30155fc0ef
[clang] static operators should evaluate object argument (#68485)
### Description

clang don't evaluate the object argument of `static operator()` and
`static operator[]` currently, for example:

```cpp
#include <iostream>

struct Foo {
    static int operator()(int x, int y) {
        std::cout << "Foo::operator()" << std::endl;
        return x + y;
    }
    static int operator[](int x, int y) {
        std::cout << "Foo::operator[]" << std::endl;
        return x + y;
    }
};
Foo getFoo() {
    std::cout << "getFoo()" << std::endl;
    return {};
}
int main() {
    std::cout << getFoo()(1, 2) << std::endl;
    std::cout << getFoo()[1, 2] << std::endl;
}
```

`getFoo()` is expected to be called, but clang don't call it currently
(17.0.2). This PR fixes this issue.

Fixes #67976.

### Walkthrough

- **clang/lib/Sema/SemaOverload.cpp**
- **`Sema::CreateOverloadedArraySubscriptExpr` &
`Sema::BuildCallToObjectOfClassType`**
Previously clang generate `CallExpr` for static operators, ignoring the
object argument. In this PR `CXXOperatorCallExpr` is generated for
static operators instead, with the object argument as the first
argument.
  - **`TryObjectArgumentInitialization`**
`const` / `volatile` objects are allowed for static methods, so that we
can call static operators on them.
- **clang/lib/CodeGen/CGExpr.cpp**
  - **`CodeGenFunction::EmitCall`**
CodeGen changes for `CXXOperatorCallExpr` with static operators: emit
and ignore the object argument first, then emit the operator call.
- **clang/lib/AST/ExprConstant.cpp**
  - **`‎ExprEvaluatorBase::handleCallExpr‎`**
Evaluation of static operators in constexpr also need some small changes
to work, so that the arguments won't be out of position.
- **clang/lib/Sema/SemaChecking.cpp**
  - **`Sema::CheckFunctionCall`**
Code for argument checking also need to be modify, or it will fail the
test `clang/test/SemaCXX/overloaded-operator-decl.cpp`.

### Tests

- **Added:**
    - **clang/test/AST/ast-dump-static-operators.cpp**
      Verify the AST generated for static operators.
    - **clang/test/SemaCXX/cxx2b-static-operator.cpp**
Static operators should be able to be called on const / volatile
objects.
- **Modified:**
    - **clang/test/CodeGenCXX/cxx2b-static-call-operator.cpp**
    - **clang/test/CodeGenCXX/cxx2b-static-subscript-operator.cpp**
      Matching the new CodeGen.

### Documentation

- **clang/docs/ReleaseNotes.rst**
  Update release notes.

---------

Co-authored-by: Shafik Yaghmour <shafik@users.noreply.github.com>
Co-authored-by: cor3ntin <corentinjabot@gmail.com>
Co-authored-by: Aaron Ballman <aaron@aaronballman.com>
2024-01-30 13:09:05 -05:00
cor3ntin
ad1a65fcac
[Clang][C++26] Implement Pack Indexing (P2662R3). (#72644)
Implements https://isocpp.org/files/papers/P2662R3.pdf

The feature is exposed as an extension in older language modes.
Mangling is not yet supported and that is something we will have to do before release.
2024-01-27 10:23:38 +01:00
Timm Baeder
4e7cf1b1ed
[clang][Interp] Add an EvaluationResult class (#71315)
Add an `EvaluationResult` class. This contains the result either as a
`Pointer` or as a `APValue`.

This way, we can inspect the result of the evaluation and diagnose
problems with it (e.g. uninitialized fields in global initializers or
pointers pointing to things they shouldn't point to).
2024-01-19 10:08:03 +01:00
cor3ntin
e90e43fb9c
[Clang][NFC] Rename CXXMethodDecl::isPure -> is VirtualPure (#78463)
To avoid any possible confusion with the notion of pure function and the
gnu::pure attribute.
2024-01-18 15:30:58 +01:00
Jonas Hahnfeld
844f8335f2
Fix crash with modules and constexpr destructor (#69076)
With modules, serialization might omit the outer ExprWithCleanups
as it calls ParmVarDecl::getDefaultArg(). Complementary to fixing
this in a separate change, make the code more robust by adding a
FullExpressionRAII and avoid the llvm_unreachable in the added test
clang/test/Modules/pr68702.cpp.

Closes https://github.com/llvm/llvm-project/issues/68702
2024-01-15 08:40:26 +01:00
Ben Jackson
c88d73164a
[clang] Crash when referencing capture in static lambda (#74661)
The constant evaluator could try to reference a lambda capture in a
static lambda call operator. Static lambdas can't have captures, so we
simply abort. Either the lambda needs to be made non-static, or the
capture (and reference to it) need to be removed.

Fixes: https://github.com/llvm/llvm-project/issues/74608
2023-12-12 07:30:23 +01:00
Jie Fu
3ec6c72551 [AST] Fix -Wlogical-op-parentheses in ExprConstant.cpp (NFC)
llvm-project/clang/lib/AST/ExprConstant.cpp:5645:74: error: '&&' within '||' [-Werror,-Wlogical-op-parentheses]
 5645 |       (Definition->isConstexpr() || Info.CurrentCall->CanEvalMSConstexpr &&
      |                                  ~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
 5646 |                                         Definition->hasAttr<MSConstexprAttr>()))
      |                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
llvm-project/clang/lib/AST/ExprConstant.cpp:5645:74: note: place parentheses around the '&&' expression to silence this warning
 5645 |       (Definition->isConstexpr() || Info.CurrentCall->CanEvalMSConstexpr &&
      |                                                                          ^
      |                                     (
 5646 |                                         Definition->hasAttr<MSConstexprAttr>()))
      |
      |                                                                               )
1 error generated.
2023-12-09 19:13:30 +08:00
Richard Dzenis
b3e6ff3319
[clang-cl] Add support for [[msvc::constexpr]] C++11 attribute (#71300)
This commit introduces support for the MSVC-specific C++11-style
attribute `[[msvc::constexpr]]`, which was introduced in MSVC 14.33.
The semantics of this attribute are enabled only under
MSVC compatibility (`-fms-compatibility-version`) 14.33 and higher.
Additionally, the default value of `_MSC_VER` has been raised to 1433.

The current implementation lacks support for:
- `[[msvc::constexpr]]` constructors (see #72149);
  at the time of this implementation, such support would have required
  an unreasonable number of changes in Clang.
- `[[msvc::constexpr]] return ::new` (constexpr placement new) from
  non-std namespaces (see #74924).

Relevant to: #57696
2023-12-09 14:35:38 +04:00
Younan Zhang
c1ad363e6e
[clang] Use the materialized temporary's type while creating the APValue (#73355)
See https://github.com/llvm/llvm-project/issues/72025 for the bug and
its diagnosis.
2023-12-01 15:20:04 +08:00
Serge Pavlov
e620035a28
[clang] Use current rounding mode for float inc/dec (#73770)
Increment and decrement are equivalent to adding or subtracting 1. For
the floating-point values these operations depend on the current
rounding mode. Teach constant evaluator to perform ++ and -- according
to the current floating-point environment.

Pull request: https://github.com/llvm/llvm-project/pull/73770
2023-11-30 17:33:35 +07:00
Timm Baeder
a79a5611bd
[clang] Classify vector types in __builtin_classify_type (#73299) 2023-11-24 14:40:58 +01:00
Timm Baeder
965d301dff
[clang][Interp] Implement __builtin_classify_type (#71972)
This adds some infrastructure for unevaluated builtin calls, and uses the implementation from ExprConstant.cpp
2023-11-17 16:13:23 +01:00
Timm Baeder
ea316625d1
[clang] Add bitint classification for __builtin_classify_type (#72036)
See #71911
2023-11-17 08:31:25 +01:00
Timm Baeder
f5b378b0d6
[clang] Use new interpreter in EvaluateAsConstantExpr if requested (#70763)
EvaluateAsConstantExpr() uses ::EvaluateInPlace() directly, which does
not use the new interpreter if requested. Do it here, which is the same
pattern we use in EvaluateAsInitializer.
2023-11-15 08:29:22 +01:00
philnik777
4cc791bc98
[Clang] Add __datasizeof (#67805)
The data size is required for implementing the `memmove` optimization
for `std::copy`, `std::move` etc. correctly as well as replacing
`__compressed_pair` with `[[no_unique_address]]` in libc++. Since the
compiler already knows the data size, we can avoid some complexity by
exposing that information.
2023-11-13 11:00:07 +01:00
Vlad Serebrennikov
3e6ce58701 [clang][NFC] Refactor StringLiteral::StringKind
This patch converts `StringLiteral::StringKind` to a scoped enum in namespace scope. This enabled forward-declarations of this enum where necessary, e.g. for `preferred_type` annotation for bit-fields.
2023-11-05 12:30:49 +03:00
Serge Pavlov
fc7198b799
[clang] Additional FP classification functions (#69041)
C language standard defined library functions `iszero`, `issignaling`
and `issubnormal`, which did not have counterparts among clang builtin
functions. This change adds new functions:

    __builtin_iszero
    __builtin_issubnormal
    __builtin_issignaling

They provide builtin implementation for the missing standard functions.

Pull request: https://github.com/llvm/llvm-project/pull/69041
2023-11-01 12:10:54 +07:00
Vlad Serebrennikov
49fd28d960 [clang][NFC] Refactor ArrayType::ArraySizeModifier
This patch moves `ArraySizeModifier` before `Type` declaration so that it's complete at `ArrayTypeBitfields` declaration. It's also converted to scoped enum along the way.
2023-10-31 18:06:34 +03:00
DaPorkchop_
b45236f133
[clang] Implement constexpr bit_cast for vectors (#66894)
This makes __builtin_bit_cast support converting to and from vector
types in a constexpr context.
2023-10-30 11:15:36 -07:00
Takuya Shimizu
b88a9f9670
[clang][ExprConst] Fix crash on uninitialized array subobject (#67817)
https://reviews.llvm.org/D146358 was assuming that all subobjects have
their own name (`SubobjectDecl`), but it was not true for array
elements.

Fixes https://github.com/llvm/llvm-project/issues/67317
2023-10-27 14:11:27 +09:00
Timm Bäder
f8b7506e2d [clang][NFC] Move a variable into the closest scope
AllocType is not used anywhere else.
2023-10-26 11:40:43 +02:00
Shafik Yaghmour
b8e06933a2
[Clang] Ensure zero-init is not overridden when initializing a base class in a constant expression context (#70150)
During constant evaluation when value-initializing a class if the base
class was default-initialized it would undue the previously
zero-initialized class members. This fixes the way we handle default
initialization to avoid initializing over an already initialized member
to an indeterminate value.

Fixes: https://github.com/llvm/llvm-project/issues/69890
2023-10-25 10:18:40 -07:00
Timm Bäder
aaaece65a8 [clang][ExprConst] Handle 0 type size in builtin_memcpy etc.
Differential Revision: https://reviews.llvm.org/D157252
2023-10-24 06:48:09 +02:00
Lawrence Benson
de65b6bec6
[Clang] Add __builtin_vectorelements to get number of elements in vector (#69010)
Adds a new `__builtin_vectorelements()` function which returns the
number of elements for a given vector either at compile-time for
fixed-sized vectors, e.g., created via `__attribute__((vector_size(N)))`
or at runtime via a call to `@llvm.vscale.i32()` for scalable vectors,
e.g., SVE or RISCV V.

The new builtin follows a similar path as `sizeof()`, as it essentially
does the same thing but for the number of elements in vector instead of
the number of bytes. This allows us to re-use a lot of the existing
logic to handle types etc.

A small side addition is `Type::isSizelessVectorType()`, which we need
to distinguish between sizeless vectors (SVE, RISCV V) and sizeless
types (WASM).

This is the [corresponding
discussion](https://discourse.llvm.org/t/new-builtin-function-to-get-number-of-lanes-in-simd-vectors/73911).
2023-10-19 10:45:08 +02:00
Timm Bäder
b4343aba9f [clang][ExprConst] Short-circuit ConstantExpr evaluation
ConstantExprs already have a value attached we can just return here.

Differential Revision: https://reviews.llvm.org/D155548
2023-10-10 13:27:03 +02:00
cor3ntin
49666ec038
[Clang] Fix constant evaluating a captured variable in a lambda (#68090)
with an explicit parameter.

We tried to read a pointer to a non-existent `This` APValue when
constant-evaluating an explicit object lambda call operator (the `this`
pointer is never set in explicit object member functions)

Fixes #68070
2023-10-05 10:17:50 +02:00
Timm Baeder
5ef904b5da
[clang][ExprConst] Don't try to evaluate value-dependent DeclRefExprs (#67778)
The Expression here migth be value dependent, which makes us run into an
assertion later on. Just bail out early.

Fixes #67690
2023-10-05 08:42:34 +02:00
Corentin Jabot
af4751738d [C++] Implement "Deducing this" (P0847R7)
This patch implements P0847R7 (partially),
CWG2561 and CWG2653.

Reviewed By: aaron.ballman, #clang-language-wg

Differential Revision: https://reviews.llvm.org/D140828
2023-10-02 14:33:02 +02:00
isuckatcs
c496aa34c0
[clang] Fix a crash from nested ArrayInitLoopExpr (#67722)
This patch makes sure that everything is cleaned up properly
when ExprConstant evaluates an ArrayInitLoopExpr.

Fixes #57135
2023-09-29 19:12:49 +02:00