Bug Summary

File:home/maarten/src/libreoffice/core/sc/source/core/tool/sharedformula.cxx
Warning:line 121, column 1
Potential leak of memory pointed to by 'xGroup2.px'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name sharedformula.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SC_DLLIMPLEMENTATION -D SC_INFO_OSVERSION="LINUX" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/mdds/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/clew/source/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sc/source/core/inc -I /home/maarten/src/libreoffice/core/sc/source/filter/inc -I /home/maarten/src/libreoffice/core/sc/source/ui/inc -I /home/maarten/src/libreoffice/core/sc/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sc/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sc/source/core/tool/sharedformula.cxx
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10#include <sharedformula.hxx>
11#include <calcmacros.hxx>
12#include <tokenarray.hxx>
13#include <listenercontext.hxx>
14#include <document.hxx>
15#include <grouparealistener.hxx>
16#include <refdata.hxx>
17
18namespace sc {
19
20const ScFormulaCell* SharedFormulaUtil::getSharedTopFormulaCell(const CellStoreType::position_type& aPos)
21{
22 if (aPos.first->type != sc::element_type_formula)
23 // Not a formula cell block.
24 return nullptr;
25
26 sc::formula_block::iterator it = sc::formula_block::begin(*aPos.first->data);
27 std::advance(it, aPos.second);
28 const ScFormulaCell* pCell = *it;
29 if (!pCell->IsShared())
30 // Not a shared formula.
31 return nullptr;
32
33 return pCell->GetCellGroup()->mpTopCell;
34}
35
36bool SharedFormulaUtil::splitFormulaCellGroup(const CellStoreType::position_type& aPos, sc::EndListeningContext* pCxt)
37{
38 SCROW nRow = aPos.first->position + aPos.second;
39
40 if (aPos.first->type != sc::element_type_formula)
8
Assuming 'element_type_formula' is equal to field 'type'
9
Taking false branch
41 // Not a formula cell block.
42 return false;
43
44 if (aPos.second == 0)
10
Assuming field 'second' is not equal to 0
11
Taking false branch
45 // Split position coincides with the block border. Nothing to do.
46 return false;
47
48 sc::formula_block::iterator it = sc::formula_block::begin(*aPos.first->data);
49 std::advance(it, aPos.second);
50 ScFormulaCell& rTop = **it;
51 if (!rTop.IsShared())
12
Assuming the condition is false
13
Taking false branch
52 // Not a shared formula.
53 return false;
54
55 if (nRow == rTop.GetSharedTopRow())
14
Assuming the condition is false
15
Taking false branch
56 // Already the top cell of a shared group.
57 return false;
58
59 ScFormulaCellGroupRef xGroup = rTop.GetCellGroup();
60
61 SCROW nLength2 = xGroup->mpTopCell->aPos.Row() + xGroup->mnLength - nRow;
62 ScFormulaCellGroupRef xGroup2;
63 if (nLength2 > 1)
16
Assuming 'nLength2' is > 1
17
Taking true branch
64 {
65 xGroup2.reset(new ScFormulaCellGroup);
18
Memory is allocated
66 xGroup2->mbInvariant = xGroup->mbInvariant;
67 xGroup2->mpTopCell = &rTop;
68 xGroup2->mnLength = nLength2;
69 xGroup2->mpCode = xGroup->mpCode->Clone();
70 }
71
72 xGroup->mnLength = nRow - xGroup->mpTopCell->aPos.Row();
73 ScFormulaCell& rPrevTop = *sc::formula_block::at(*aPos.first->data, aPos.second - xGroup->mnLength);
74
75#if USE_FORMULA_GROUP_LISTENER1
76 // At least group area listeners will have to be adapted. As long as
77 // there's no update mechanism and no separated handling of group area and
78 // other listeners, all listeners of this group's top cell are to be reset.
79 if (nLength2
18.1
'nLength2' is not equal to 0
)
19
Taking true branch
80 {
81 // If a context exists it has to be used to not interfere with
82 // ScColumn::maBroadcasters iterators, which the EndListeningTo()
83 // without context would do when removing a broadcaster that had its
84 // last listener removed.
85 if (pCxt
19.1
'pCxt' is null
)
20
Taking false branch
86 rPrevTop.EndListeningTo(*pCxt);
87 else
88 rPrevTop.EndListeningTo( rPrevTop.GetDocument(), nullptr, ScAddress( ScAddress::UNINITIALIZED));
89 rPrevTop.SetNeedsListening(true);
90
91 // The new group or remaining single cell needs a new listening.
92 rTop.SetNeedsListening(true);
93 }
94#endif
95
96 if (xGroup->mnLength == 1)
21
Assuming field 'mnLength' is not equal to 1
22
Taking false branch
97 {
98 // The top group consists of only one cell. Ungroup this.
99 ScFormulaCellGroupRef xNone;
100 rPrevTop.SetCellGroup(xNone);
101 }
102
103 // Apply the lower group object to the lower cells.
104#if DEBUG_COLUMN_STORAGE0
105 if (xGroup2->mpTopCell->aPos.Row() + size_t(xGroup2->mnLength) > aPos.first->position + aPos.first->size)
106 {
107 cerr << "ScColumn::SplitFormulaCellGroup: Shared formula region goes beyond the formula block. Not good." << endl;
108 cerr.flush();
109 abort();
110 }
111#endif
112 sc::formula_block::iterator itEnd = it;
113 std::advance(itEnd, nLength2);
114 for (; it != itEnd; ++it)
23
Loop condition is false. Execution continues on line 120
115 {
116 ScFormulaCell& rCell = **it;
117 rCell.SetCellGroup(xGroup2);
118 }
119
120 return true;
121}
24
Potential leak of memory pointed to by 'xGroup2.px'
122
123bool SharedFormulaUtil::splitFormulaCellGroups(const ScDocument& rDoc, CellStoreType& rCells, std::vector<SCROW>& rBounds)
124{
125 if (rBounds.empty())
4
Assuming the condition is false
5
Taking false branch
126 return false;
127
128 // Sort and remove duplicates.
129 std::sort(rBounds.begin(), rBounds.end());
130 std::vector<SCROW>::iterator it = std::unique(rBounds.begin(), rBounds.end());
131 rBounds.erase(it, rBounds.end());
132
133 it = rBounds.begin();
134 SCROW nRow = *it;
135 CellStoreType::position_type aPos = rCells.position(nRow);
136 if (aPos.first == rCells.end())
6
Taking false branch
137 return false;
138
139 bool bSplit = splitFormulaCellGroup(aPos, nullptr);
7
Calling 'SharedFormulaUtil::splitFormulaCellGroup'
140 std::vector<SCROW>::iterator itEnd = rBounds.end();
141 for (++it; it != itEnd; ++it)
142 {
143 nRow = *it;
144 if (rDoc.ValidRow(nRow))
145 {
146 aPos = rCells.position(aPos.first, nRow);
147 if (aPos.first == rCells.end())
148 return bSplit;
149 bSplit |= splitFormulaCellGroup(aPos, nullptr);
150 }
151 }
152 return bSplit;
153}
154
155bool SharedFormulaUtil::joinFormulaCells(
156 const CellStoreType::position_type& rPos, ScFormulaCell& rCell1, ScFormulaCell& rCell2 )
157{
158 if( rCell1.GetDocument().IsDelayedFormulaGrouping())
159 {
160 rCell1.GetDocument().AddDelayedFormulaGroupingCell( &rCell1 );
161 rCell1.GetDocument().AddDelayedFormulaGroupingCell( &rCell2 );
162 return false;
163 }
164
165 ScFormulaCell::CompareState eState = rCell1.CompareByTokenArray(rCell2);
166 if (eState == ScFormulaCell::NotEqual)
167 return false;
168
169 // Formula tokens equal those of the previous formula cell.
170 ScFormulaCellGroupRef xGroup1 = rCell1.GetCellGroup();
171 ScFormulaCellGroupRef xGroup2 = rCell2.GetCellGroup();
172 if (xGroup1)
173 {
174 if (xGroup2)
175 {
176 // Both cell 1 and cell 2 are shared. Merge them together.
177 if (xGroup1.get() == xGroup2.get())
178 // They belong to the same group.
179 return false;
180
181 // Set the group object from cell 1 to all cells in group 2.
182 xGroup1->mnLength += xGroup2->mnLength;
183 size_t nOffset = rPos.second + 1; // position of cell 2
184 for (size_t i = 0, n = xGroup2->mnLength; i < n; ++i)
185 {
186 ScFormulaCell& rCell = *sc::formula_block::at(*rPos.first->data, nOffset+i);
187 rCell.SetCellGroup(xGroup1);
188 }
189 }
190 else
191 {
192 // cell 1 is shared but cell 2 is not.
193 rCell2.SetCellGroup(xGroup1);
194 ++xGroup1->mnLength;
195 }
196 }
197 else
198 {
199 if (xGroup2)
200 {
201 // cell 1 is not shared, but cell 2 is already shared.
202 rCell1.SetCellGroup(xGroup2);
203 xGroup2->mpTopCell = &rCell1;
204 ++xGroup2->mnLength;
205 }
206 else
207 {
208 // neither cells are shared.
209 assert(rCell1.aPos.Row() == static_cast<SCROW>(rPos.first->position + rPos.second))(static_cast <bool> (rCell1.aPos.Row() == static_cast<
SCROW>(rPos.first->position + rPos.second)) ? void (0) :
__assert_fail ("rCell1.aPos.Row() == static_cast<SCROW>(rPos.first->position + rPos.second)"
, "/home/maarten/src/libreoffice/core/sc/source/core/tool/sharedformula.cxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 xGroup1 = rCell1.CreateCellGroup(2, eState == ScFormulaCell::EqualInvariant);
211 rCell2.SetCellGroup(xGroup1);
212 }
213 }
214
215 return true;
216}
217
218bool SharedFormulaUtil::joinFormulaCellAbove( const CellStoreType::position_type& aPos )
219{
220 if (aPos.first->type != sc::element_type_formula)
221 // This is not a formula cell.
222 return false;
223
224 if (aPos.second == 0)
225 // This cell is already the top cell in a formula block; the previous
226 // cell is not a formula cell.
227 return false;
228
229 ScFormulaCell& rPrev = *sc::formula_block::at(*aPos.first->data, aPos.second-1);
230 ScFormulaCell& rCell = *sc::formula_block::at(*aPos.first->data, aPos.second);
231 sc::CellStoreType::position_type aPosPrev = aPos;
232 --aPosPrev.second;
233 return joinFormulaCells(aPosPrev, rPrev, rCell);
234}
235
236void SharedFormulaUtil::unshareFormulaCell(const CellStoreType::position_type& aPos, ScFormulaCell& rCell)
237{
238 if (!rCell.IsShared())
239 return;
240
241 ScFormulaCellGroupRef xNone;
242 sc::CellStoreType::iterator it = aPos.first;
243
244 // This formula cell is shared. Adjust the shared group.
245 if (rCell.aPos.Row() == rCell.GetSharedTopRow())
246 {
247 // Top of the shared range.
248 const ScFormulaCellGroupRef& xGroup = rCell.GetCellGroup();
249 if (xGroup->mnLength == 2)
250 {
251 // Group consists of only two cells. Mark the second one non-shared.
252#if DEBUG_COLUMN_STORAGE0
253 if (aPos.second+1 >= aPos.first->size)
254 {
255 cerr << "ScColumn::UnshareFormulaCell: There is no next formula cell but there should be!" << endl;
256 cerr.flush();
257 abort();
258 }
259#endif
260 ScFormulaCell& rNext = *sc::formula_block::at(*it->data, aPos.second+1);
261 rNext.SetCellGroup(xNone);
262 }
263 else
264 {
265 // Move the top cell to the next formula cell down.
266 ScFormulaCell& rNext = *sc::formula_block::at(*it->data, aPos.second+1);
267 xGroup->mpTopCell = &rNext;
268 }
269 --xGroup->mnLength;
270 }
271 else if (rCell.aPos.Row() == rCell.GetSharedTopRow() + rCell.GetSharedLength() - 1)
272 {
273 // Bottom of the shared range.
274 const ScFormulaCellGroupRef& xGroup = rCell.GetCellGroup();
275 if (xGroup->mnLength == 2)
276 {
277 // Mark the top cell non-shared.
278#if DEBUG_COLUMN_STORAGE0
279 if (aPos.second == 0)
280 {
281 cerr << "ScColumn::UnshareFormulaCell: There is no previous formula cell but there should be!" << endl;
282 cerr.flush();
283 abort();
284 }
285#endif
286 ScFormulaCell& rPrev = *sc::formula_block::at(*it->data, aPos.second-1);
287 rPrev.SetCellGroup(xNone);
288 }
289 else
290 {
291 // Just shorten the shared range length by one.
292 --xGroup->mnLength;
293 }
294 }
295 else
296 {
297 // In the middle of the shared range. Split it into two groups.
298 ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
299 SCROW nEndRow = xGroup->mpTopCell->aPos.Row() + xGroup->mnLength - 1;
300 xGroup->mnLength = rCell.aPos.Row() - xGroup->mpTopCell->aPos.Row(); // Shorten the top group.
301 if (xGroup->mnLength == 1)
302 {
303 // Make the top cell non-shared.
304#if DEBUG_COLUMN_STORAGE0
305 if (aPos.second == 0)
306 {
307 cerr << "ScColumn::UnshareFormulaCell: There is no previous formula cell but there should be!" << endl;
308 cerr.flush();
309 abort();
310 }
311#endif
312 ScFormulaCell& rPrev = *sc::formula_block::at(*it->data, aPos.second-1);
313 rPrev.SetCellGroup(xNone);
314 }
315
316 SCROW nLength2 = nEndRow - rCell.aPos.Row();
317 if (nLength2 >= 2)
318 {
319 ScFormulaCellGroupRef xGroup2;
320 xGroup2.reset(new ScFormulaCellGroup);
321 ScFormulaCell& rNext = *sc::formula_block::at(*it->data, aPos.second+1);
322 xGroup2->mpTopCell = &rNext;
323 xGroup2->mnLength = nLength2;
324 xGroup2->mbInvariant = xGroup->mbInvariant;
325 xGroup2->mpCode = xGroup->mpCode->Clone();
326#if DEBUG_COLUMN_STORAGE0
327 if (xGroup2->mpTopCell->aPos.Row() + size_t(xGroup2->mnLength) > it->position + it->size)
328 {
329 cerr << "ScColumn::UnshareFormulaCell: Shared formula region goes beyond the formula block. Not good." << endl;
330 cerr.flush();
331 abort();
332 }
333#endif
334 sc::formula_block::iterator itCell = sc::formula_block::begin(*it->data);
335 std::advance(itCell, aPos.second+1);
336 sc::formula_block::iterator itCellEnd = itCell;
337 std::advance(itCellEnd, xGroup2->mnLength);
338 for (; itCell != itCellEnd; ++itCell)
339 {
340 ScFormulaCell& rCell2 = **itCell;
341 rCell2.SetCellGroup(xGroup2);
342 }
343 }
344 else
345 {
346 // Make the next cell non-shared.
347 sc::formula_block::iterator itCell = sc::formula_block::begin(*it->data);
348 std::advance(itCell, aPos.second+1);
349 ScFormulaCell& rCell2 = **itCell;
350 rCell2.SetCellGroup(xNone);
351 }
352 }
353
354 rCell.SetCellGroup(xNone);
355}
356
357void SharedFormulaUtil::unshareFormulaCells(const ScDocument& rDoc, CellStoreType& rCells, std::vector<SCROW>& rRows)
358{
359 if (rRows.empty())
1
Assuming the condition is false
2
Taking false branch
360 return;
361
362 // Sort and remove duplicates.
363 std::sort(rRows.begin(), rRows.end());
364 rRows.erase(std::unique(rRows.begin(), rRows.end()), rRows.end());
365
366 // Add next cell positions to the list (to ensure that each position becomes a single cell).
367 std::vector<SCROW> aRows2;
368 for (const auto& rRow : rRows)
369 {
370 if (rRow > rDoc.MaxRow())
371 break;
372
373 aRows2.push_back(rRow);
374
375 if (rRow < rDoc.MaxRow())
376 aRows2.push_back(rRow+1);
377 }
378
379 // Remove duplicates again (the vector should still be sorted).
380 aRows2.erase(std::unique(aRows2.begin(), aRows2.end()), aRows2.end());
381
382 splitFormulaCellGroups(rDoc, rCells, aRows2);
3
Calling 'SharedFormulaUtil::splitFormulaCellGroups'
383}
384
385void SharedFormulaUtil::startListeningAsGroup( sc::StartListeningContext& rCxt, ScFormulaCell** ppSharedTop )
386{
387 ScFormulaCell& rTopCell = **ppSharedTop;
388 assert(rTopCell.IsSharedTop())(static_cast <bool> (rTopCell.IsSharedTop()) ? void (0)
: __assert_fail ("rTopCell.IsSharedTop()", "/home/maarten/src/libreoffice/core/sc/source/core/tool/sharedformula.cxx"
, 388, __extension__ __PRETTY_FUNCTION__))
;
389
390#if USE_FORMULA_GROUP_LISTENER1
391 ScDocument& rDoc = rCxt.getDoc();
392 rDoc.SetDetectiveDirty(true);
393
394 ScFormulaCellGroupRef xGroup = rTopCell.GetCellGroup();
395 const ScTokenArray* pCode = xGroup->mpCode.get();
396 assert(pCode == rTopCell.GetCode())(static_cast <bool> (pCode == rTopCell.GetCode()) ? void
(0) : __assert_fail ("pCode == rTopCell.GetCode()", "/home/maarten/src/libreoffice/core/sc/source/core/tool/sharedformula.cxx"
, 396, __extension__ __PRETTY_FUNCTION__))
;
397 if (pCode->IsRecalcModeAlways())
398 {
399 rDoc.StartListeningArea(
400 BCA_LISTEN_ALWAYSScRange( ScAddress( 0, SCROW_MAX, 0 ), ScAddress( 0, SCROW_MAX
, 0 ) )
, false,
401 xGroup->getAreaListener(ppSharedTop, BCA_LISTEN_ALWAYSScRange( ScAddress( 0, SCROW_MAX, 0 ), ScAddress( 0, SCROW_MAX
, 0 ) )
, true, true));
402 }
403
404 formula::FormulaToken** p = pCode->GetCode();
405 formula::FormulaToken** pEnd = p + pCode->GetCodeLen();
406 for (; p != pEnd; ++p)
407 {
408 const formula::FormulaToken* t = *p;
409 switch (t->GetType())
410 {
411 case formula::svSingleRef:
412 {
413 const ScSingleRefData* pRef = t->GetSingleRef();
414 ScAddress aPos = pRef->toAbs(rDoc, rTopCell.aPos);
415 ScFormulaCell** pp = ppSharedTop;
416 ScFormulaCell** ppEnd = ppSharedTop + xGroup->mnLength;
417 for (; pp != ppEnd; ++pp)
418 {
419 if (!aPos.IsValid())
420 break;
421
422 rDoc.StartListeningCell(rCxt, aPos, **pp);
423 if (pRef->IsRowRel())
424 aPos.IncRow();
425 }
426 }
427 break;
428 case formula::svDoubleRef:
429 {
430 const ScSingleRefData& rRef1 = *t->GetSingleRef();
431 const ScSingleRefData& rRef2 = *t->GetSingleRef2();
432 ScAddress aPos1 = rRef1.toAbs(rDoc, rTopCell.aPos);
433 ScAddress aPos2 = rRef2.toAbs(rDoc, rTopCell.aPos);
434
435 ScRange aOrigRange(aPos1, aPos2);
436 ScRange aListenedRange = aOrigRange;
437 if (rRef2.IsRowRel())
438 aListenedRange.aEnd.IncRow(xGroup->mnLength-1);
439
440 if (aPos1.IsValid() && aPos2.IsValid())
441 {
442 rDoc.StartListeningArea(
443 aListenedRange, true,
444 xGroup->getAreaListener(ppSharedTop, aOrigRange, !rRef1.IsRowRel(), !rRef2.IsRowRel()));
445 }
446 }
447 break;
448 default:
449 ;
450 }
451 }
452
453 ScFormulaCell** pp = ppSharedTop;
454 ScFormulaCell** ppEnd = ppSharedTop + xGroup->mnLength;
455 for (; pp != ppEnd; ++pp)
456 {
457 ScFormulaCell& rCell = **pp;
458 rCell.SetNeedsListening(false);
459 }
460
461#else
462 ScFormulaCell** pp = ppSharedTop;
463 ScFormulaCell** ppEnd = ppSharedTop + rTopCell.GetSharedLength();
464 for (; pp != ppEnd; ++pp)
465 {
466 ScFormulaCell& rFC = **pp;
467 rFC.StartListeningTo(rCxt);
468 }
469#endif
470}
471
472}
473
474/* vim:set shiftwidth=4 softtabstop=4 expandtab: */